Scala中具有隐式参数的函数的类型 [英] Type of a function with Implicit parameters in Scala
问题描述
我想有一个带有参数的高阶函数,该函数接受一个特定的隐式参数.
I would like to have a higher order function that takes in parameter a function that accepts a specific implicit parameter.
更准确地说,我正在尝试制作一个函数,该函数采用依赖于隐式上下文的Future
创建方法,并返回不依赖于上下文的方法.
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)
}
但是如果我调用provideCtx(foo)
,编译器会抱怨隐式执行上下文丢失.
but if I call provideCtx(foo)
, the compiler complains about the implicit execution context missing.
我正在处理一个ExecutionContext的事实不是很重要.我想找到的是如何编写参数类型以接受带有特定类型隐式参数的函数.我知道隐式部分是一个可修改的参数,因此实际上我有一个类似这样的函数:ExecutionContext => Int => Future[Float]
,而且我很确定在运行时,JVM不知道ExecutionContext是隐式的,但是我可以不能使编译器理解这一点.
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.
推荐答案
问题是foo
是方法而不是函数,并且直到隐式应用之后才尝试使用eta-expansion(将方法转换为函数) .有关详细信息,请参见语言规范的6.26.2节;有关以下问题,此问题额外的讨论.
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))
我不确定是否可以使用更通用的解决方案(至少没有某种形式的反射等),因为我们甚至不能在没有c的情况下引用foo
(当然,在方法调用中除外).隐式作用域.
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.
这篇关于Scala中具有隐式参数的函数的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!