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))
}