短形式的lambda在内部函数中不起作用

时间:2018-09-17 07:51:02

标签: scala

阅读Advanced Scala With Cats可以在第60页上看到此行:

fa.map(g(f(_))) == fa.map(f).map(g)

我正在尝试做类似的事情:

  val l = List(1, 2, 3)
  def g(v: Int) = v + 1 
  def f(v: Int) = v * 2

  l.map(g(f(_)))

我收到此错误:

Error:(25, 12) type mismatch;
 found   : Int => Int
 required: Int
  l.map(g(f(_)))

没关系:

  l.map(x => g(f(x)))
  l.map(g(_))

无法理解为什么我的示例不起作用,但在书中是正确的。

2 个答案:

答案 0 :(得分:2)

val l = List(1, 2, 3)
  def g(v: Int) = v + 1 
  def f(v: Int) = v * 2

  l.map(g(f(_)))

我将尝试将您的l.map(g(f(_)))分成相等的步骤

val  fun1 =  f(_) // this returns a partially applied function Int => Int.

然后

g(fun1)  // will give you error because function g requires int as an argument whereas we are passing func1: Int => Int as input. This is the exact issue comes when you do g(f(_)).

您提到的替代方法是正确的。我的想法是证明Scala的功能组合能力。我想在其他可用方法上做同样的事情。

 val fun = f _ andThen g _
 l.map(fun)

compose也可以完成相同的操作。

val fun1 =  g _ compose f _
l.map(fun1)

请记住,合成仅适用于一元函数。

答案 1 :(得分:0)

我将通过以下方式执行此操作:

scala> val g:Int => Int = _ + 1
g: Int => Int = <function1>

scala> val f:Int => Int = _ * 2
f: Int => Int = <function1>

scala> val l = List(1, 2, 3)
l: List[Int] = List(1, 2, 3)

scala> l map (g compose f)
res0: List[Int] = List(3, 5, 7)

在声明def时,您会得到一个方法,该方法要求在代码中使用其名称时提供一个参数。 将函数声明为val时,会得到一个纯Function1实例,并且可以正常使用功能组合器对其进行操作。