Reputation: 2022
Reading Advanced Scala With Cats
I can see this line on page 60:
fa.map(g(f(_))) == fa.map(f).map(g)
I'm trying to do something like:
val l = List(1, 2, 3)
def g(v: Int) = v + 1
def f(v: Int) = v * 2
l.map(g(f(_)))
And I'm getting this error:
Error:(25, 12) type mismatch;
found : Int => Int
required: Int
l.map(g(f(_)))
This is okay:
l.map(x => g(f(x)))
l.map(g(_))
Can't understand why my example doesn't work, but in the book it is correct.
Upvotes: 3
Views: 68
Reputation: 5710
val l = List(1, 2, 3)
def g(v: Int) = v + 1
def f(v: Int) = v * 2
l.map(g(f(_)))
I will try to split your l.map(g(f(_)))
into equivalent steps
val fun1 = f(_) // this returns a partially applied function Int => Int.
then
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(_)).
The alternatives that you have mentioned is correct. My idea here is to demonstrate the ability of Scala’s function composition. I would like to do the same thing other available approaches.
val fun = f _ andThen g _
l.map(fun)
Same can be done with compose
as well.
val fun1 = g _ compose f _
l.map(fun1)
Remember that composition is available only on Unary functions.
Upvotes: 2
Reputation: 3435
I would do this in following way:
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)
When declaring a def
you get a method which expects an argument provided when using its name in the code.
When declaring a function as a val
you get a pure Function1
instance and you can operate on them with functional combinators normally.
Upvotes: 0