# Case for implicits

I’m trying to understand implicits, and I have a situation where I think I’d like to use implicit, but I don’t see how to do it.
As I understand the implicit parameter MUST be the final parameter, and must be its own parameter group. However, in my case I need another parameter group to be the final one so I can use partial evaluation.

Take a look at this example. `limit` is a function with two parameter groups. If I call `limit(math.sin,0.1,almostEqual(0.01))` then I get a function which when given an `x` will evaluate the limit as `sin` approaches `x` to within 1% accuracy. Similarly the function call `derivative(math.sin,0.01,almostEqual(0.001))` returns a function which when given `x` will return the value of the derivative of `sin` at `x` to within 0.1% accuracy.

``````  def limit(f:Double=>Double, delta:Double, test:(Double,Double)=>Boolean)(x:Double):Double = {
def recur(h:Double, previous:Double):Double = {
val improved = f(x+h)
if(test(improved,previous))
improved
else
recur(h/2,improved)
}
recur(delta/2,f(x+delta))
}

def derivative(f:Double=>Double,delta:Double,test:(Double,Double)=>Boolean)(x:Double) = {

def estimate(h: Double): Double = {
(f(x + h) - f(x)) / h
}
limit(estimate, delta, test)(0.0)
}
``````

I’d like to make the `test` parameter implicit. The best that I can think of is to make it optional (with a default) but not implicit. So I could change the above call to the following `limit(math.sin,0.1)()` So I could rewrite it as follows. However, that does not allow the caller to define the default test, it only allows the caller to accept my suggested default.

``````  def limit(f:Double=>Double, delta:Double)(test:(Double,Double)=>Boolean = almostEqual(0.1))(x:Double):Double = {
def recur(h:Double, previous:Double):Double = {
val improved = f(x+h)
if(test(improved,previous))
improved
else
recur(h/2,improved)
}
recur(delta/2,f(x+delta))
}
``````

One possible solution is the following. Change `limit` to a function which explicitly returns `Double=>Double`.

``````  def limit(f:Double=>Double, delta:Double)(implicit test:(Double,Double)=>Boolean):Double=>Double = {
(x: Double) => {
def recur(h: Double, previous: Double): Double = {
val improved = f(x + h)
if (test(improved, previous))
improved
else
recur(h / 2, improved)
}
recur(delta / 2, f(x + delta))
}
}
``````

However, then when I call `limit(sin,0.1)(Pi/2)` the compiler (at least IntelliJ) thinks `(Pi/2)` is the value of the implicit parameter `test` rather than the value of `x`.

Try to assign the function to a variable. Only then apply the value. Note that we can always set the implicit parameters explicitly. When you set the second parameter group, you are in effect setting the implicit parameter explicitly.

``````  val f = limit(sin,0.1)  // compiler gets a chance to "inject" parameter
val r = f(Pi/2)
``````

HTHs

1 Like

or something to the effect of the following also works:

`````` def limit(f:Double=>Double, delta:Double, x:Double)(implicit test:(Double,Double)=>Boolean):Double = {
def recur(h: Double, previous: Double): Double = {
val improved = f(x + h)
if (test(improved, previous))
improved
else
recur(h / 2, improved)
}

recur(delta / 2, f(x + delta))
}

val f = limit(sin,0.1,_)
val r = f(Pi/2)
``````

I.e., the caller has to curry the function himself.

Yep. More than one way to skin that cat 