将函数隐式参数传递给高阶函数后,函数隐式参数不再如此
Function implicit parameters not any more so after passing it to a higher order function
在 Scala 中,您可以执行以下操作:
def foo(implicit v: Int) = println(v);
def h(x: Int) = { implicit val i: Int = x; foo }
h(42)
> 42
h
调用获取 foo
引用作为闭包。
尝试将 foo
作为参数传递给 h
并不奇怪:
def g(x: Int)(f: Int => Unit) = { implicit val i: Int = x; f }
但这行不通:
g(1)(foo)
> error: could not find implicit value for parameter v: Int
我认为正在发生的事情是 foo
被调用作为实际参数的评估。 对吗?
当传递一个带有普通参数列表(非隐式)的函数时,该函数未被计算:
def foo2(v: Int) = println("Foo2")
g(1)(foo2)
> Int => Unit = <function1>
这是预期结果,foo2
评估未尝试作为实际参数的评估。
为什么在没有隐式值可用时将 foo
计算为实际参数?
赋值也是如此:
val fooref: Int => Unit = foo
> error: could not find implicit value for parameter v: Int
这就像因为 Int => Unit
与 Int
参数被标记为隐式的函数不匹配,编译器将其丢弃为有效的实际参数并因此尝试对其求值。未找到声明的隐式值来完成调用。
如果是这样,用隐式参数表达函数类型的方式应该是什么?
不幸的是,函数不能有隐式参数——只有方法可以。
在表达式g(1)(foo)
中,foo
从方法转换为函数(也称为作为 eta 展开)。 Scala 规范的 section 6.26.2 声明隐式参数在 之前 eta 扩展应用。
看到这张票:implicit methods behave suboptimally when used non-implicitly
函数 g
的 f
参数的类型是 Function1[Int, Unit]
。 Function1[A, B]
是单一方法 apply(a: A): B
的特征,其中 a
不是隐式的。因此,您不能从 foo
创建 Function1[Int, Unit]
的实例 - 它没有正确的签名。
在 Scala 中,您可以执行以下操作:
def foo(implicit v: Int) = println(v);
def h(x: Int) = { implicit val i: Int = x; foo }
h(42)
> 42
h
调用获取 foo
引用作为闭包。
尝试将 foo
作为参数传递给 h
并不奇怪:
def g(x: Int)(f: Int => Unit) = { implicit val i: Int = x; f }
但这行不通:
g(1)(foo)
> error: could not find implicit value for parameter v: Int
我认为正在发生的事情是 foo
被调用作为实际参数的评估。 对吗?
当传递一个带有普通参数列表(非隐式)的函数时,该函数未被计算:
def foo2(v: Int) = println("Foo2")
g(1)(foo2)
> Int => Unit = <function1>
这是预期结果,foo2
评估未尝试作为实际参数的评估。
为什么在没有隐式值可用时将 foo
计算为实际参数?
赋值也是如此:
val fooref: Int => Unit = foo
> error: could not find implicit value for parameter v: Int
这就像因为 Int => Unit
与 Int
参数被标记为隐式的函数不匹配,编译器将其丢弃为有效的实际参数并因此尝试对其求值。未找到声明的隐式值来完成调用。
如果是这样,用隐式参数表达函数类型的方式应该是什么?
不幸的是,函数不能有隐式参数——只有方法可以。
在表达式g(1)(foo)
中,foo
从方法转换为函数(也称为作为 eta 展开)。 Scala 规范的 section 6.26.2 声明隐式参数在 之前 eta 扩展应用。
看到这张票:implicit methods behave suboptimally when used non-implicitly
函数 g
的 f
参数的类型是 Function1[Int, Unit]
。 Function1[A, B]
是单一方法 apply(a: A): B
的特征,其中 a
不是隐式的。因此,您不能从 foo
创建 Function1[Int, Unit]
的实例 - 它没有正确的签名。