Issue
-----

### First approach

If would like to have

```
trait Distance extends ((SpacePoint, SpacePoint) => Double)

object EuclideanDistance extends Distance {
  override def apply(sp1: SpacePoint, sp2: SpacePoint): Double = ???
}

trait Kernel extends (((Distance)(SpacePoint, SpacePoint)) => Double)

object GaussianKernel extends Kernel {
  override def apply(distance: Distance)(sp1: SpacePoint, sp2: SpacePoint): Double = ???
}

```

However the `apply` of `object GaussianKernel extends Kernel` is not an excepted `override` to the `apply` of `trait Kernel`.

### Second approach - ***EDIT:*** turns out this works afterall...

Alternatively I could write

```
trait Kernel extends ((Distance) => ( (SpacePoint, SpacePoint)  => Double))

object GaussianKernel extends Kernel {
    override def apply(distance: Distance): (SpacePoint, SpacePoint) => Double =
        (sp1: SpacePoint, sp2: SpacePoint) =>
            math.exp(-math.pow(distance(sp1, sp2), 2) / (2))
}

```

but am not sure this is currying...

***EDIT:*** Turns out that I can use this second approach in a currying fashion. I think it is exactly what the typical currying is, only without the syntactic sugar.

---

Explanation of the idea
-----------------------

The idea is this: For my algorithm I need a [Kernel](https://en.wikipedia.org/wiki/Kernel_method). This kernel calculates a metric for two vectors in space - here `SpacePoint`s. For that the Kernel requires a way to calculate the distance between the two `SpacePoint`s. Both distance and kernel should be exchangeable ([open-closed principle](https://en.wikipedia.org/wiki/Open/closed_principle)), thus I declare them as traits (in Java I had them declared as interfaces). Here I use the [Euclidean Distance](https://en.wikipedia.org/wiki/Euclidean_distance) (not shown) and the [Gaussian Kernel](https://en.wikipedia.org/wiki/Gaussian_function). Why the currying? Later when using those things, the `distance` is going to be more or less the same for all measurements, while the `SpacePoint`s will change all the time. Again, trying to stay true to the open-closed principle. Thus, in a first step I would like the `GaussianKernel` to be pre-configured (if you will) with a distance and return a `Function` that can be feed later in the program with the `SpacePoint`s (I am sure the code is wrong, just to give you an idea what I am aiming at):

```
val myFirstKernel  = GaussianKernel(EuclideanDistance)
val mySecondKernel = GaussianKernel(FancyDistance)
val myThirdKernel  = EpanechnikovKernel(EuclideanDistance)
// ...  lots lof code ...
val firstOtherClass  = new OtherClass(myFirstKernel)
val secondOtherClass = new OtherClass(mySecondKernel)
val thirdOtherClass  = new OtherClass(myThirdKernel)

// ...  meanwhile in "OtherClass" ...
class OtherClass(kernel: Kernel) {
    val thisSpacePoint = ??? // ... fancy stuff going on ...
    val thisSpacePoint = ??? // ... fancy stuff going on ...
    val calculatedKernel = kernel(thisSpacePoint, thatSpacePoint)
}

```

---

Questions
---------

1. How do I build my trait?
2. Since `distance` can be different for different `GaussianKernel`s - should `GaussianKernel` be a class instead of an object?
3. Should I partially apply `GaussianKernel` instead of currying?
4. Is my approach bad and `GaussianKernel` should be a class that stores the `distance` in a field?