函数隐式参数在将其传递给更高阶函数后不再如此

Pab*_*lgo 8 scala function implicit implicits

在Scala中,您可以执行以下操作:

def foo(implicit v: Int) = println(v);
def h(x: Int) = { implicit val i: Int = x; foo }

h(42)
> 42
Run Code Online (Sandbox Code Playgroud)

hcall将foo引用作为闭包.

尝试传递fooh参数并不奇怪:

def g(x: Int)(f: Int => Unit) = { implicit val i: Int = x; f }
Run Code Online (Sandbox Code Playgroud)

但它不会起作用:

g(1)(foo)
> error: could not find implicit value for parameter v: Int
Run Code Online (Sandbox Code Playgroud)

我认为它正在发生的是foo被称为实际参数的评估.是对的吗?

当传递具有普通参数列表的函数(非隐式)时,不会评估该函数:

def foo2(v: Int) = println("Foo2")
g(1)(foo2)
> Int => Unit = <function1>
Run Code Online (Sandbox Code Playgroud)

这是预期结果,并且foo2不作为实际参数的评估尝试评估.

foo当没有隐含值可用时,为什么将其评估为实际参数?

分配也是如此:

val fooref: Int => Unit = foo
> error: could not find implicit value for parameter v: Int
Run Code Online (Sandbox Code Playgroud)

这就像因为Int => UnitInt参数被标记为隐式的函数不匹配,编译器将其作为有效的实际参数丢弃,因此尝试对其进行评估.找不到声明的隐含值来完成调用.

如果是这种情况,那么用隐式参数表达函数类型的方式是什么?

dca*_*tro 11

不幸的是,函数不能有隐式参数 - 只有方法可以.

在表达式中g(1)(foo),foo从一个方法转换为一个函数(也称为eta-expansion).和部分6.26.2 Scala的规格的规定,隐式参数被施加之前 ETA-扩张.

请参阅此票证:隐式方法在非隐式使用时表现为次优