# How lift function works?

Dear all,
I’,m reading the red book. here is an example code:

def lift[A,B](f: A => B): Option[A] => Option[B] = {
maybeA => maybeA map f
}
val absO: Option[Double] => Option[Double] = lift(math.abs)

How does it work? where the maybeA is come from with the type of Option?!

The return type of `lift` is a function and the implementation is just a lambda.

Is not different of saying: `val f = (x: Int) => x + 1`
Thus, `maybeA` is just the name that was given to the input of the function, and since we already told the compiler the return would be `Option[A] => Option[B]` then it knows that `maybeA` is a `Option[A]`

@BalmungSan Could u please write a non-lambda version to clarify it better?
you mean if we define the return type compiler do some magic and implement some code for us?
I mean we should create some Option types from A and B by ourselves. How does is work?

Not sure how would you write a non-lambda version.
We are returning a function, if you do not understand functions then you should not be reading the red book yet.

There is a lot of info about functions in the Scala Tour: Introduction | Tour of Scala | Scala Documentation

BTW, `lift` is not a function is a method, they are different.

1 Like

`maybeA` is the argument of the lambda function that is returned by the method `lift`.

Simpler example: consider `val a = 1`. Now, `x => x + a` would almost be a valid lambda, except that the argument type is missing. But if the type is provided by the context, it is fine, e.g.

``````val a = 1
(x => x + a): (Int => Int)
``````

Alternatively:

``````val a = 1
val lam: Int => Int = x => x+a
``````

Or, as the return value of a method:

``````def m(a: Int): Int => Int = x => x + a
``````
2 Likes

but get confusing.
i will think about it and return again

You haven’t mentioned it, so I will just clarify anyway. As you are reading books, ESPECIALLY the FP Red Book, I highly recommend you use the REPL, Scala Worksheet (available in both IntelliJ+Scala-Plugin or VSCode+Metals), and/or Scastie.

IOW, it is really important that you have direct concrete experience with these concepts. Trying to learn via just thinking and abstracting is just making things many more times difficult for yourself. And I am speaking from personal direct experience. You can save yourself many hours by playing in one of these tools directly with the Scala code. And, you will answer your own original question much more quickly.

3 Likes

Thanks for your friendly suggestion. yes REPL, intelliJ and i are good friends

1 Like

@BalmungSan @chaotic3quilibrium @curoli
Thanks guys, i’m getting functional

1 Like

Since `A => B` is special syntax for `Function1[A, B]`, a non-lambda version would be explicitly writing a type that implements `Function1[Option[A], Option[B]`

``````def lift[A, B](f: A => B): Option[A] => Option[B] = new Function1[Option[A], Option[B]] {
override def apply(maybeA: Option[A]): Option[B] = maybeA map f
}
``````

You can see that `maybeA` maps to the name for the parameter to `apply`.

And that anonymous instance is isomorphic to a class that takes the function as a constructor parameter.

``````
class Lift[-A, +B](f: A => B) extends Function1[Option[A], Option[B]] {
override def apply(maybeA: Option[A]): Option[B] = maybeA map f
}

def lift[A, B](f: A => B): Option[A] => Option[B] = new Lift(f)
``````

The lambda syntax `maybeA => maybeA map f` is therefore shorthand for the above, where the compiler generates the class and implementation and instantiates it for you, and possibly does something more efficient in cases where that’s possible.

2 Likes