faoxis
faoxis

Reputation: 2022

Short form of lambda doesn't work in inner function

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

Answers (2)

Balaji Reddy
Balaji Reddy

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

Alexander Arendar
Alexander Arendar

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

Related Questions