New Lambdas in Scala 3
Wiem Zine Elabidine, Software Engineer at LiveIntent
2
Lambda expression
val identity: Int => Int = (a: Int) => a
3
Lambda expression
val identity: Int => Int = (a: Int) => a
val identity: Function1[Int, Int] = new Function1[Int, Int] {
def apply(a: Int): Int = a
}
4
Lambda expression
val identity: Int => Int = a => a
val listF = List(identity)
5
Method
def identity(a: Int): Int = a
6
Method
def identityMethod(a: Int): Int = a
val listF = List(identityMethod)
^
error: missing argument list for method identityMethod
Unapplied methods are only converted to functions when
a function type is expected.
You can make this conversion explicit by writing
`identityMethod _` or `identityMethod(_)` instead of
`identityMethod`.
In Scala 2
7
Eta expansion in Scala 2
When we want to convert a def to a function,
Manual conversion:
def identityMethod(a: Int): Int = a
val identityFunction: Int => Int = identityMethod _
val listF = List(identityMethod _)
8
Automatic eta-expansion in Scala 3
The eta expansion has been improved.
def identityMethod(a: Int): Int = a
val identityFunction: Int => Int = a => a
List(identityMethod) is similar to List(identityFunction)
9
Automatic eta-expansion in Scala 3
The eta expansion has been improved.
def identityMethod(a: Int): Int = a
The identityMethod _ syntax is deprecated
10
Automatic eta-expansion in Scala 3
The eta expansion has been improved.
def f() = println("hello")
List(f)
^
method f must be called with () argument
11
Automatic eta-expansion in Scala 3
The eta expansion has been improved.
def f() = println("hello")
List(() => f())
12
Typed lambda
identity: (a: A) => a
13
Generic methods in Scala2
identity: (a: A) => a
def identity[A] = (a: A) => a
or
def identity[A](a: A): A= a
14
Polymorphic function type in Scala3
identity: (a: A) => a
val identity = [A] => (a: A) => a
> val identity: PolyFunction{apply: [A](a: A): A} = <function1>
15
Context function
A ?=> B
Type Lambdas
17
Proper type
n: Int
Int
18
Type constructor
A => List[A]
List[A]
19
Type constructor
A => List[A]
List[A]
type F = [A] =>> List[A]
20
Type constructor
A => List[A]
List[A]
type F = [A] =>> List[A]
type F[A] = List[A]
21
Type constructor
List[A]
type F = [A] =>> List[A]
type F[A] = List[A]
val f= [A] => (a: A) => List[A]
def f[A]: List[A]
22
Type constructor
(E, A) => Either[E, A]
Either[E, A]
23
Type constructor
(E, A) => Either[E, A]
Either[E, A]
type F = [E, A] =>> Either[E, A]
24
Type constructor
(E, A) => Either[E, A]
Either[E, A]
type F = [E, A] =>> Either[E, A]
type F[E, A] = Either[E, A]
25
Higher kinded type
(A => F[A]) => Container[F]
trait Container[F[_]]
26
Higher kinded type
type X = [F[_]] =>> Container[F]
(A => F[A]) => Container[F]
trait Container[F[_]]
27
Higher kinded type
type X = [F[_]] =>> Container[F]
type X = [F[_]] =>> Container[A =>> F[A]]
(A => F[A]) => Container[F]
trait Container[F[_]]
28
Higher kinded type
type X = [F[_]] =>> Container[F]
type X = [F[_]] =>> Container[A =>> F[A]]
type X[F[_]] = Container[F]
(A => F[A]) => Container[F]
trait Container[F[_]]
29
type Lambdas
type ListContainer = Container[List]
30
type Lambdas
type EitherContainer = Container[Either]
^^^^^^
Type argument Either does not have the same kind as its bound [_$1]
31
Partial application
type EitherContainer = Container[Either]
^^^^^^
Type argument Either does not have the same kind as its bound [_$1]
val f: (A, B) => C
val f1: A => C = ???
val f2: B => C = ???
32
Partial application
type EitherContainer = Container[Either]
^^^^^^
Type argument Either does not have the same kind as its bound [_$1]
val f: (A, B) => C
val f1: A => C = f(_, b)
val f2: B => C = f(a, _)
33
type EitherContainer[A] = Container[({type T[E] = Either[E, A]})#T]
type Lambdas in Scala 2
34
trait MyEither[A] {
type T[E] = Either[E, A]
}
type EitherContainer[A] = Container[MyEither[A]#T]
type Lambdas in Scala 2
35
type EitherContainer[A] = Container[Either[*, A]]
type Lambdas using Kind projector plugin
36
type EitherContainer[A] = Container[[E] =>> Either[E, A]]
type Lambdas using Scala 3
37
type EitherF[A] = [E] =>> Either[E, A]
type EitherContainer = [A] =>> Container[EitherF[A]]
type Lambdas using Scala 3
38
type EitherF[A] = [E] =>> Either[E, A]
type EitherContainer = [A] =>> Container[EitherF[A]]
type Lambdas using Scala 3
EitherF[Int][String]
Question
40
Polymorphic function type in Scala3
val identity = [A] => (a: A) => a
> val identity: PolyFunction{apply: [A](a: A): A} = <function1>
Similar syntax as SAM
41
Is there a plan to enable SAM to trait that has a
polymorphic functions?
trait Example[A]:
def f(a: A): A = a
val v: Example[Int] = (a: Int) => a
Example
trait Example:
def f[A](a: A): A = a
val v: Example = [A] => (a: A) => a
OR
42
Follow me on twitter: @WiemZin
Thanks!
43
Credits
◂ Presentation template by Slidesgo
◂ Icons by Flaticon
◂ Images & infographics by Freepik
◂ Author introduction slide photo created by freestockcenter - Freepik.com
◂ Text & Image slide photo created by tzido - Freepik.com
◂ Big image slide photo created by tzido - Freepik.com
Thank you!

New lambdas