FP in Scala 
Walk with monsters (ADTs)
Applicative Functor 
// id function: 
// def id[A](a: A): A = a 
// compose function: 
// def compose[A,B,C](f: B => C, g: 
A => B): A => C = 
// a => f(g(a)) 
trait Functor[F[_]] { 
def map[A,B](fa: F[A])(f: A => 
B): F[B] 
} 
// Functor Law 
// identity: map(x)(id) == x 
// composition: map(a)(compose(f, 
g)) == map(map(a,g), f) 
trait Applictive[F[_]] extends Functor 
[F] { 
def unit[A](a: => A): F[A] 
def ap[A,B](la: F[A])(f: F[A => B]): F 
[B] 
override def map[A, B](la: F[A])(f: A 
=> B): F[B] = 
ap(la)(unit(f)) 
} 
// Applicative Law 
// identity: ap(a, unit(id)) == a 
// composition: ap(ap(a, g), f) == ap(a, ap 
(g, ap(f, unit(compose)))) 
// homomorphism: ap(unit(a), unit(f)) == 
unit(f(a)) 
// interchange: ap(unit(a), f) == ap(f, unit(f 
=> f(x))) 
trait Monad[F[_]] extends Applictive[F] { 
def unit[A](a: => A): F[A] 
def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B] 
override def ap[A,B](la: F[A])(f: F[A => B]): F 
[B] = 
flatMap(f)(t1 => flatMap(la)(t2 => unit(t1 
(t2)))) 
override def map[A,B](ma: F[A])(f: A => B): F 
[B] = 
flatMap(ma)(a => unit(f(a))) 
} 
// Monad Law 
// left identity: f(a) == flatmap(unit(a), f) 
// right identity: a == flatMap(a, x => unit(x)) 
// associativity: flatMap(a, x => flatMap(f(x), g)) == 
flatMap(flatMap(a, f), g)
Applicative Functor 
Functor 
Take one function 
with one input and 
apply onto the 
value inside 
content 
Monad 
Take function(s) 
that can apply to 
values inside 
contents, and also 
can change 
behavior in the 
process of apply 
function(s) 
Applicative Functor 
Take one function 
with multiple input 
and apply onto the 
values inside 
contents
Applicative Functor 
Functor 
def oneVarFunc: Int => Int = 
{ 
_ + 1 
} 
val x1 = Some(1) 
x1.map(oneVarFunc) 
get Some(2) 
Monad 
val x1 = Some(1) 
val x2 = Some(2) 
val x3 = Some(3) 
x1.flatMap { r1 => { 
r1 match { 
case 1 => x2.flatMap { 
r2 => Some(r1 * r2) 
} 
case _ => x3.flatMap { 
r3 => Some(r1 + r3) 
} 
} 
} 
get Some(2) 
Applicative Functor 
def twoVarFunc: (Int, Int) => Int = {_ + _} 
val x1 = Some(1) 
val x2 = Some(2) 
val x3 = None 
x2.ap(x1.map(twoVarFunc.curried)) 
get Some(3) 
x3.ap(x2.map(twoVarFunc.curried)) 
get None 
def zip[U](that: Future[U]): Future[(T, U)]
Why Applicative Functor 
1. Because it is less restrictive, it in fact easier to reason. 
2. It is also a key part of Traversable ADT 
3. Not all Applicative functor is Monad 
a. Indefinite length Stream 
b. Multidimensional Array 
4. Different Applicative functor can compose, different 
Monad can not compose (has to use Monad 
Transformer) 
a. def compose[A,B,C](f: A => M[B], g: B => M[C]): A => 
M[C] = ???
Monad Transformer 
Want a Applicative/Monad that has multiple 
property by compose 2 or more 
Applicatives/Monads, for example. 
List[Option[Future[Int]]] 
Can this type be also a Applicative/Monad, has ap 
and flatMap defined. Can we just have generic way 
to do this instead of write one for every type?
Applicative Composition 
trait Functor[F[_]] { 
def map[A,B](fa: F[A])(f: A => B): F[B] 
} 
trait Applictive[F[_]] extends Functor[F] { 
def unit[A](a: => A): F[A] 
def ap[A,B](la: F[A])(f: F[A => B]): F[B] 
override def map[A, B](la: F[A])(f: A => B): F[B] = 
ap(la)(unit(f)) 
def apply2[A, B, C](fa: => F[A], fb: => F[B])(f: (A, B) => C): F 
[C] = 
ap(fb)(map(fa)(f.curried)) 
} 
trait CompositionApplicative[F[_], G[_]] extends Applicative 
[({type λ[α] = F[G[α]]})#λ] { 
implicit def F: Applicative[F] 
implicit def G: Applicative[G] 
def ap[A, B](fa: => F[G[A]])(f: => F[G[A => B]]): F[G[B]] 
= 
F.apply2(f, fa)((ff, ga) => G.ap(ga)(ff)) 
def unit[A](a: => A): F[G[A]] = F.unit(G.unit(a)) 
} 
Yes, we can do it for Applicative in a generic way
Monad Composition 
trait Monad[F[_]] extends Applictive[F] { 
def unit[A](a: => A): F[A] 
def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B] 
override def ap[A,B](la: F[A])(f: F[A => B]): F[B] = 
flatMap(f)(t1 => flatMap(la)(t2 => unit(t1(t2)))) 
override def map[A,B](ma: F[A])(f: A => B): F[B] = 
flatMap(ma)(a => unit(f(a))) 
} 
case class OptionT[M[_],A](value: M[Option[A]]) { 
self => 
def unit(a: A)(implicit m: Monad[M]): OptionT[M, A] = 
new OptionT[M, A](m.unit(Some(a))) 
def flatMap[B](f: A => OptionT[M, B])(implicit m: Monad[M]) 
: OptionT[M, B] = new OptionT[M, B]( 
m.flatMap(self.value) { 
case None => m.unit(None) 
case Some(a) => f(a).value 
}) 
} 
No, we can not do it for Monad in a generic way
Foldable 
trait Semigroup[A] { 
def op(a: A, b: A): A 
} 
trait Monoid[A] extends Semigroup[A] { 
val zero: A 
} 
trait Foldable[F[_]] { 
def foldMap[A,B](fa: F[A], f: A => B)(implicit m: Monoid 
[B]): B 
/* 
def fold[M: Monoid](t: F[M]): M // also called reduce with 
variance 
def foldRight[A, B](t: F[A], z: => B, f: (A, B) => B): B 
def foldLeft[A, B](t: F[A], z: B, f: (B, A) => B): B 
def foldr1[A, B](t: F[A], f: (A, => A) => A): Option[A] 
def foldl1[A, B](t: F[A], f: (A, A) => A): Option[A] 
*/ 
} 
This the definition of 
Monoid and Foldable, 
simple and generic but very 
very useful. 
In fact, it is the conceptual 
base for MapReduce 
With Applicative and 
Foldable, we will introduce 
Traversable
Foldable 
val IntMonoid = new Monoid[Int] { 
def op(a: Int, b: Int): Int = a * b 
val zero: Int = 1 
} 
val ListFodable = new Foldable[List] { 
def foldMap[A, B](t: List[A], f: A => B)(implicit m: Monoid[B]): B = 
t.foldRight(m.zero)((a,b) => m.op(f(a), b)) 
} 
object test { 
val x1 = List(1,2,3,4) 
val r1 = ListFodable.foldMap(x1, (x: Int) => x)(IntMonoid) 
} 
Foldable use a Monoid to 
go through a structure, and 
in the process return some 
aggregated value with the 
original structure collapsed.
Traversable 
Traversable is a generalized Foldable 
Foldable use a Monoid to go through a structure, and in the 
process return some aggregated value with the original 
structure collapsed. 
Traversable use a Applicative go through a structure, and 
in the process return some aggregated value with the 
original structure kept.
Traversable 
trait Foldable[F[_]] { 
def foldMap[A, M: Monoid](t: F[A], f: A => M): M 
} 
trait Applicative[F[_]] extends Functor[F]{ 
def unit[A](a: => A): F[A] 
def ap[A,B](fa: F[A])(fab: F[A => B]): F[B] 
override def map[A,B](t: F[A])(f: A => B): F[B] = 
ap(t)(unit(f)) 
} 
type Const[A, B] = A 
implicit def monoidApplicative[M](m: Monoid[M]) = 
new Applicative[({ type f[x] = Const[M, x] })#f] { 
def unit[A](a: => A): M = m.zero 
override def ap[A,B](m1: M)(m2: M): M = m.op 
(m1, m2) 
} 
import scala.Predef.identity 
trait Traversable[T[_]] extends Functor[T] with Foldable[T] { 
def traverse[F[_]: Applicative, A, B](f: A => F[B], t: T[A]): F[T[B]] // = 
sequence(map(t)(f)) 
def sequence[F[_]: Applicative, A](tfa: T[F[A]]): F[T[A]] = traverse(identity 
[F[A]], tfa) 
// def mapM[M[_]: Monad, A, B](f: A => M[B], t: T[A]): M[T[B]] = ??? 
// def sequenceM[M[_]: Monad](tmb: T[M[B]]): M[T[B]] = ??? 
type Id[A] = A 
val Identity = new Applicative[Id] { 
def unit[A](a: => A) = a 
def ap[A,B](a: A)(f: A => B): B = f(a) 
} 
override def map[A, B](k: T[A])(f: A => B) = traverse[Id, A, B](f, k) 
(Identity) 
override def foldMap[A, M](as: T[A], f: A => M)(implicit m: Monoid[M]): 
M= 
traverse[({type f[x] = Const[M,x]})#f,A,Nothing](f, as)(monoidApplicative 
(m))
Traversable 
As you can see, transverse preserves the structure, it is the 
strength and weakness. 
The sequence method is very interesting, F[G[A]], if F is a 
Traversable, and G is a Applicative, it in fact can be 
reversed as G[F[A]] 
It also works with Monad as every Monad is a Applicative 
(does not means Monad composable, as you need a 
Traversable) 
Traversable is composable, like Applicative
Traversable in Action 
import scala.language.higherKinds 
val OptionApplicatable = new Applicative[Option] { 
def unit[A](a: => A) = Some(a) 
def ap[A,B](a: Option[A])(f: Option[A => B]): Option[B] = 
f.flatMap { 
t1 => a.flatMap { 
t2 => unit(t1(t2)) 
} 
} 
} 
val ListTraversable = new Traversable[List] { 
def traverse[F[_], A, B](f: A => F[B], t: List[A])(implicit m: 
Applicative[F]): F[List[B]] = 
t.foldRight(m.unit(List[B]()))((a, fbs) => m.zip(f(a),fbs)(_ 
:: _)) 
} 
object test { 
val x1 = List(1,2,3,4) 
val x2 = List(Option(1), Option(2), Option(3)) 
val x3 = List(Option(1), Option(2), Option(3), Option(null)) 
def f1(a: Int): Option[Int] = Some(a) 
val r1 = ListTraversable.traverse(f1, x1)(OptionApplicatable) 
val r2 = ListTraversable.sequence(x2)(OptionApplicatable) 
val r3 = ListTraversable.sequence(x3)(OptionApplicatable) 
}

Fp in scala with adts

  • 1.
    FP in Scala Walk with monsters (ADTs)
  • 2.
    Applicative Functor //id function: // def id[A](a: A): A = a // compose function: // def compose[A,B,C](f: B => C, g: A => B): A => C = // a => f(g(a)) trait Functor[F[_]] { def map[A,B](fa: F[A])(f: A => B): F[B] } // Functor Law // identity: map(x)(id) == x // composition: map(a)(compose(f, g)) == map(map(a,g), f) trait Applictive[F[_]] extends Functor [F] { def unit[A](a: => A): F[A] def ap[A,B](la: F[A])(f: F[A => B]): F [B] override def map[A, B](la: F[A])(f: A => B): F[B] = ap(la)(unit(f)) } // Applicative Law // identity: ap(a, unit(id)) == a // composition: ap(ap(a, g), f) == ap(a, ap (g, ap(f, unit(compose)))) // homomorphism: ap(unit(a), unit(f)) == unit(f(a)) // interchange: ap(unit(a), f) == ap(f, unit(f => f(x))) trait Monad[F[_]] extends Applictive[F] { def unit[A](a: => A): F[A] def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B] override def ap[A,B](la: F[A])(f: F[A => B]): F [B] = flatMap(f)(t1 => flatMap(la)(t2 => unit(t1 (t2)))) override def map[A,B](ma: F[A])(f: A => B): F [B] = flatMap(ma)(a => unit(f(a))) } // Monad Law // left identity: f(a) == flatmap(unit(a), f) // right identity: a == flatMap(a, x => unit(x)) // associativity: flatMap(a, x => flatMap(f(x), g)) == flatMap(flatMap(a, f), g)
  • 3.
    Applicative Functor Functor Take one function with one input and apply onto the value inside content Monad Take function(s) that can apply to values inside contents, and also can change behavior in the process of apply function(s) Applicative Functor Take one function with multiple input and apply onto the values inside contents
  • 4.
    Applicative Functor Functor def oneVarFunc: Int => Int = { _ + 1 } val x1 = Some(1) x1.map(oneVarFunc) get Some(2) Monad val x1 = Some(1) val x2 = Some(2) val x3 = Some(3) x1.flatMap { r1 => { r1 match { case 1 => x2.flatMap { r2 => Some(r1 * r2) } case _ => x3.flatMap { r3 => Some(r1 + r3) } } } get Some(2) Applicative Functor def twoVarFunc: (Int, Int) => Int = {_ + _} val x1 = Some(1) val x2 = Some(2) val x3 = None x2.ap(x1.map(twoVarFunc.curried)) get Some(3) x3.ap(x2.map(twoVarFunc.curried)) get None def zip[U](that: Future[U]): Future[(T, U)]
  • 5.
    Why Applicative Functor 1. Because it is less restrictive, it in fact easier to reason. 2. It is also a key part of Traversable ADT 3. Not all Applicative functor is Monad a. Indefinite length Stream b. Multidimensional Array 4. Different Applicative functor can compose, different Monad can not compose (has to use Monad Transformer) a. def compose[A,B,C](f: A => M[B], g: B => M[C]): A => M[C] = ???
  • 6.
    Monad Transformer Wanta Applicative/Monad that has multiple property by compose 2 or more Applicatives/Monads, for example. List[Option[Future[Int]]] Can this type be also a Applicative/Monad, has ap and flatMap defined. Can we just have generic way to do this instead of write one for every type?
  • 7.
    Applicative Composition traitFunctor[F[_]] { def map[A,B](fa: F[A])(f: A => B): F[B] } trait Applictive[F[_]] extends Functor[F] { def unit[A](a: => A): F[A] def ap[A,B](la: F[A])(f: F[A => B]): F[B] override def map[A, B](la: F[A])(f: A => B): F[B] = ap(la)(unit(f)) def apply2[A, B, C](fa: => F[A], fb: => F[B])(f: (A, B) => C): F [C] = ap(fb)(map(fa)(f.curried)) } trait CompositionApplicative[F[_], G[_]] extends Applicative [({type λ[α] = F[G[α]]})#λ] { implicit def F: Applicative[F] implicit def G: Applicative[G] def ap[A, B](fa: => F[G[A]])(f: => F[G[A => B]]): F[G[B]] = F.apply2(f, fa)((ff, ga) => G.ap(ga)(ff)) def unit[A](a: => A): F[G[A]] = F.unit(G.unit(a)) } Yes, we can do it for Applicative in a generic way
  • 8.
    Monad Composition traitMonad[F[_]] extends Applictive[F] { def unit[A](a: => A): F[A] def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B] override def ap[A,B](la: F[A])(f: F[A => B]): F[B] = flatMap(f)(t1 => flatMap(la)(t2 => unit(t1(t2)))) override def map[A,B](ma: F[A])(f: A => B): F[B] = flatMap(ma)(a => unit(f(a))) } case class OptionT[M[_],A](value: M[Option[A]]) { self => def unit(a: A)(implicit m: Monad[M]): OptionT[M, A] = new OptionT[M, A](m.unit(Some(a))) def flatMap[B](f: A => OptionT[M, B])(implicit m: Monad[M]) : OptionT[M, B] = new OptionT[M, B]( m.flatMap(self.value) { case None => m.unit(None) case Some(a) => f(a).value }) } No, we can not do it for Monad in a generic way
  • 9.
    Foldable trait Semigroup[A]{ def op(a: A, b: A): A } trait Monoid[A] extends Semigroup[A] { val zero: A } trait Foldable[F[_]] { def foldMap[A,B](fa: F[A], f: A => B)(implicit m: Monoid [B]): B /* def fold[M: Monoid](t: F[M]): M // also called reduce with variance def foldRight[A, B](t: F[A], z: => B, f: (A, B) => B): B def foldLeft[A, B](t: F[A], z: B, f: (B, A) => B): B def foldr1[A, B](t: F[A], f: (A, => A) => A): Option[A] def foldl1[A, B](t: F[A], f: (A, A) => A): Option[A] */ } This the definition of Monoid and Foldable, simple and generic but very very useful. In fact, it is the conceptual base for MapReduce With Applicative and Foldable, we will introduce Traversable
  • 10.
    Foldable val IntMonoid= new Monoid[Int] { def op(a: Int, b: Int): Int = a * b val zero: Int = 1 } val ListFodable = new Foldable[List] { def foldMap[A, B](t: List[A], f: A => B)(implicit m: Monoid[B]): B = t.foldRight(m.zero)((a,b) => m.op(f(a), b)) } object test { val x1 = List(1,2,3,4) val r1 = ListFodable.foldMap(x1, (x: Int) => x)(IntMonoid) } Foldable use a Monoid to go through a structure, and in the process return some aggregated value with the original structure collapsed.
  • 11.
    Traversable Traversable isa generalized Foldable Foldable use a Monoid to go through a structure, and in the process return some aggregated value with the original structure collapsed. Traversable use a Applicative go through a structure, and in the process return some aggregated value with the original structure kept.
  • 12.
    Traversable trait Foldable[F[_]]{ def foldMap[A, M: Monoid](t: F[A], f: A => M): M } trait Applicative[F[_]] extends Functor[F]{ def unit[A](a: => A): F[A] def ap[A,B](fa: F[A])(fab: F[A => B]): F[B] override def map[A,B](t: F[A])(f: A => B): F[B] = ap(t)(unit(f)) } type Const[A, B] = A implicit def monoidApplicative[M](m: Monoid[M]) = new Applicative[({ type f[x] = Const[M, x] })#f] { def unit[A](a: => A): M = m.zero override def ap[A,B](m1: M)(m2: M): M = m.op (m1, m2) } import scala.Predef.identity trait Traversable[T[_]] extends Functor[T] with Foldable[T] { def traverse[F[_]: Applicative, A, B](f: A => F[B], t: T[A]): F[T[B]] // = sequence(map(t)(f)) def sequence[F[_]: Applicative, A](tfa: T[F[A]]): F[T[A]] = traverse(identity [F[A]], tfa) // def mapM[M[_]: Monad, A, B](f: A => M[B], t: T[A]): M[T[B]] = ??? // def sequenceM[M[_]: Monad](tmb: T[M[B]]): M[T[B]] = ??? type Id[A] = A val Identity = new Applicative[Id] { def unit[A](a: => A) = a def ap[A,B](a: A)(f: A => B): B = f(a) } override def map[A, B](k: T[A])(f: A => B) = traverse[Id, A, B](f, k) (Identity) override def foldMap[A, M](as: T[A], f: A => M)(implicit m: Monoid[M]): M= traverse[({type f[x] = Const[M,x]})#f,A,Nothing](f, as)(monoidApplicative (m))
  • 13.
    Traversable As youcan see, transverse preserves the structure, it is the strength and weakness. The sequence method is very interesting, F[G[A]], if F is a Traversable, and G is a Applicative, it in fact can be reversed as G[F[A]] It also works with Monad as every Monad is a Applicative (does not means Monad composable, as you need a Traversable) Traversable is composable, like Applicative
  • 14.
    Traversable in Action import scala.language.higherKinds val OptionApplicatable = new Applicative[Option] { def unit[A](a: => A) = Some(a) def ap[A,B](a: Option[A])(f: Option[A => B]): Option[B] = f.flatMap { t1 => a.flatMap { t2 => unit(t1(t2)) } } } val ListTraversable = new Traversable[List] { def traverse[F[_], A, B](f: A => F[B], t: List[A])(implicit m: Applicative[F]): F[List[B]] = t.foldRight(m.unit(List[B]()))((a, fbs) => m.zip(f(a),fbs)(_ :: _)) } object test { val x1 = List(1,2,3,4) val x2 = List(Option(1), Option(2), Option(3)) val x3 = List(Option(1), Option(2), Option(3), Option(null)) def f1(a: Int): Option[Int] = Some(a) val r1 = ListTraversable.traverse(f1, x1)(OptionApplicatable) val r2 = ListTraversable.sequence(x2)(OptionApplicatable) val r3 = ListTraversable.sequence(x3)(OptionApplicatable) }