简体   繁体   English

Scala中具有Implicit参数的函数的类型

[英]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. 我想有一个更高阶的函数,它接受一个接受特定隐式参数的函数的参数。

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. 更确切地说,我正在尝试创建一个函数,该函数采用依赖于隐式上下文的Future创建方法,并返回不依赖于上下文的方法。

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. 但如果我调用provideCtx(foo) ,编译器会抱怨缺少隐式执行上下文。

The fact that I am dealing with an ExecutionContext is not very important. 我正在处理ExecutionContext的事实并不是很重要。 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. 我理解隐式部分是一个curryed参数,所以实际上我有一个像这样的函数: ExecutionContext => Int => Future[Float] ,我很确定在运行时,jvm不知道那个ExecutionContext是隐式的,但是我不能让编译器理解它。

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. 问题是foo是一个方法,而不是一个函数,并且在隐式应用之前不会尝试eta-expansion(将方法转换为函数)。 See section 6.26.2 of the language specification for the details, and this issue for additional discussion. 有关详细信息,请参阅语言规范的第6.26.2节,有关其他讨论,请参阅此问题

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. 我不确定一个更通用的解决方案是否可行(至少没有某种反射等),因为我们甚至不能在没有隐式范围的情况下引用foo (除了在方法调用中)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM