Question

I would like to have a higher order function that takes in parameter a function that accepts a specific implicit parameter.

To be more precise, I am trying to make a function that takes a Future creation method that depends on an implicit context and returns a method that doesn't depend on the context.

To be more concrete, let's say that I have something like this:

def foo(a: Int)(implicit ctx: ExecutionContext): Future[Float] = future { somelongBar... }

I would like to do have a method like this:

def provideCtx[A](func: ExecutionContext => A): A = {
     val ctx = setupCtx
     func(ctx)
}

but if I call provideCtx(foo), the compiler complains about the implicit execution context missing.

The fact that I am dealing with an ExecutionContext is not very important. What I would like to find is how to write the parameter type to accept a function with an implicit argument of a specific type. I understand that the implicit part is a curryed argument, so that in fact I have a function like so: ExecutionContext => Int => Future[Float], and I am pretty sure that at runtime, the jvm doesn't know that that ExecutionContext is implicit, but I can't make the compiler understand that.

Was it helpful?

Solution

The problem is that foo is a method, not a function, and eta-expansion (which converts methods to functions) is not attempted until after implicit application. See section 6.26.2 of the language specification for the details, and this issue for additional discussion.

One workaround would be to write something like this:

provideCtx((ctx: ExecutionContext) => (a: Int) => foo(a)(ctx))

I'm not sure a more generic solution is possible (at least without some kind of reflection, etc.), since we can't even refer to foo (except in a method call, of course) without an implicit in scope.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top