高阶函数隐式未解析

时间:2014-09-23 15:23:58

标签: scala implicit

我有一个函数 create 将提供op: DSLContext => T的参数DSLContext:

def create[T](op: DSLContext => T)(implicit errorHandler: Throwable => Unit):Option[T] = {
  ...
  op(new DSLContext)
  ...
}

然后我将以下函数传递给 create

def query(implicit dsl:DSLContext)

这是电话

create(query)

我收到了这个编译错误:

  

找不到参数dsl:org.jooq.DSLContext的隐式值   [错误]创建(查询)

我可以通过这种方式解决此问题:create {implicit dsl => query}

但我想知道为什么编译器无法将隐式参数dsl解析为给定参数?

1 个答案:

答案 0 :(得分:4)

这里的问题是当你传递一个需要函数的方法时,编译器需要执行eta-expansion来转换它。

换句话说,方法query需要成为Function1[DSLContext, T]

但是,编译器需要解析隐式参数才能应用eta-expansion。在您的情况下,范围内没有DSLContext,因此编译器无法执行此操作。

您可以使用一个更简单的示例重现此行为,这是一个演示它的REPL会话:

scala> def foo(implicit i: Int) = "hello"
foo: (implicit i: Int)String

scala> foo _
<console>:10: error: could not find implicit value for parameter i: Int
              foo _
              ^

scala> implicit val x = 5
x: Int = 5

scala> foo _
res3: scala.collection.immutable.WrappedString = hello

其中_手动触发eta扩展。

有关记录,请参阅language reference第6.26.2段。

  

如果该方法仅采用隐式参数,则遵循§7.2的规则传递隐式参数。