阅读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(_))
无法理解为什么我的示例不起作用,但在书中是正确的。
答案 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
实例,并且可以正常使用功能组合器对其进行操作。