SlideShare a Scribd company logo
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) 
}

More Related Content

PDF
Fp in scala with adts part 2
PDF
Fp in scala part 1
PDF
Scala collection methods flatMap and flatten are more powerful than monadic f...
PDF
Functor Laws
PPTX
Monads and friends demystified
PPTX
Kleisli composition, flatMap, join, map, unit - implementation and interrelation
PDF
Functor Composition
PDF
Sequence and Traverse - Part 1
Fp in scala with adts part 2
Fp in scala part 1
Scala collection methods flatMap and flatten are more powerful than monadic f...
Functor Laws
Monads and friends demystified
Kleisli composition, flatMap, join, map, unit - implementation and interrelation
Functor Composition
Sequence and Traverse - Part 1

What's hot (20)

PDF
Monoids - Part 2 - with examples using Scalaz and Cats
PDF
Symmetry in the interrelation of flatMap/foldMap/traverse and flatten/fold/se...
PDF
Monoids, Monoids, Monoids - ScalaLove 2020
PDF
Scala. Introduction to FP. Monads
PDF
Sequence and Traverse - Part 3
PDF
Oh, All the things you'll traverse
PDF
Monoids, monoids, monoids
PDF
Monads do not Compose
PPTX
Introduction to Monads in Scala (2)
PDF
One Monad to Rule Them All
PPTX
The Essence of the Iterator Pattern
PDF
Monad presentation scala as a category
PPTX
Running Free with the Monads
PDF
Scalaz 8: A Whole New Game
PPTX
Introduction to Monads in Scala (1)
PDF
The Death of Final Tagless
PDF
Contravariant functors in scala
PDF
Functor, Apply, Applicative And Monad
PDF
Refactoring Functional Type Classes
PDF
Big picture of category theory in scala with deep dive into contravariant and...
Monoids - Part 2 - with examples using Scalaz and Cats
Symmetry in the interrelation of flatMap/foldMap/traverse and flatten/fold/se...
Monoids, Monoids, Monoids - ScalaLove 2020
Scala. Introduction to FP. Monads
Sequence and Traverse - Part 3
Oh, All the things you'll traverse
Monoids, monoids, monoids
Monads do not Compose
Introduction to Monads in Scala (2)
One Monad to Rule Them All
The Essence of the Iterator Pattern
Monad presentation scala as a category
Running Free with the Monads
Scalaz 8: A Whole New Game
Introduction to Monads in Scala (1)
The Death of Final Tagless
Contravariant functors in scala
Functor, Apply, Applicative And Monad
Refactoring Functional Type Classes
Big picture of category theory in scala with deep dive into contravariant and...
Ad

Viewers also liked (12)

PPTX
Functional Programming in Scala #4-1
PPTX
Why functional programming in C# & F#
PDF
Functional Programming in Scala: Notes
PDF
Functional Programming in Scala Reading #2
PDF
関数プログラミングことはじめ
PDF
ScalaMatsuri 2014 LT
PDF
20150207 何故scalaを選んだのか
PDF
Introduction to Functional Programming in Scala
PDF
JavaからScalaへの継続的なマイグレーション
PDF
浪江町タブレットで採用した、 Cordovaで作るHTML5のAndroidアプリのしくみ
PDF
Functional programming in scala
PDF
Introduction to Functional Programming with Scala
Functional Programming in Scala #4-1
Why functional programming in C# & F#
Functional Programming in Scala: Notes
Functional Programming in Scala Reading #2
関数プログラミングことはじめ
ScalaMatsuri 2014 LT
20150207 何故scalaを選んだのか
Introduction to Functional Programming in Scala
JavaからScalaへの継続的なマイグレーション
浪江町タブレットで採用した、 Cordovaで作るHTML5のAndroidアプリのしくみ
Functional programming in scala
Introduction to Functional Programming with Scala
Ad

Similar to Fp in scala with adts (20)

PDF
The Essence of the Iterator Pattern (pdf)
PPTX
(2015 06-16) Three Approaches to Monads
PDF
Monad and Algebraic Design in Functional Programming
PDF
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
PDF
Essence of the iterator pattern
PPT
Thesis PPT
PPT
Thesis
PDF
Functions, Types, Programs and Effects
PDF
Scala Functional Patterns
PDF
Monad Fact #4
PDF
Fp in scala part 2
PDF
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
PDF
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
PDF
Monads - Dublin Scala meetup
PDF
Monad Transformers - Part 1
PPTX
하스켈 프로그래밍 입문 4
PDF
Algebraic Data Types and Origami Patterns
PDF
Hardcore functional programming
PDF
Algebraic Thinking for Evolution of Pure Functional Domain Models
PDF
All You Need is Fold
The Essence of the Iterator Pattern (pdf)
(2015 06-16) Three Approaches to Monads
Monad and Algebraic Design in Functional Programming
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Essence of the iterator pattern
Thesis PPT
Thesis
Functions, Types, Programs and Effects
Scala Functional Patterns
Monad Fact #4
Fp in scala part 2
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Monads - Dublin Scala meetup
Monad Transformers - Part 1
하스켈 프로그래밍 입문 4
Algebraic Data Types and Origami Patterns
Hardcore functional programming
Algebraic Thinking for Evolution of Pure Functional Domain Models
All You Need is Fold

Recently uploaded (20)

PPTX
Essential Infomation Tech presentation.pptx
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
PTS Company Brochure 2025 (1).pdf.......
PPTX
L1 - Introduction to python Backend.pptx
PPTX
Reimagine Home Health with the Power of Agentic AI​
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
System and Network Administraation Chapter 3
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
top salesforce developer skills in 2025.pdf
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Essential Infomation Tech presentation.pptx
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PTS Company Brochure 2025 (1).pdf.......
L1 - Introduction to python Backend.pptx
Reimagine Home Health with the Power of Agentic AI​
CHAPTER 2 - PM Management and IT Context
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
System and Network Administraation Chapter 3
Wondershare Filmora 15 Crack With Activation Key [2025
How to Migrate SBCGlobal Email to Yahoo Easily
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
top salesforce developer skills in 2025.pdf
Upgrade and Innovation Strategies for SAP ERP Customers
Odoo Companies in India – Driving Business Transformation.pdf
How Creative Agencies Leverage Project Management Software.pdf
2025 Textile ERP Trends: SAP, Odoo & Oracle
Design an Analysis of Algorithms I-SECS-1021-03
wealthsignaloriginal-com-DS-text-... (1).pdf
Design an Analysis of Algorithms II-SECS-1021-03
Internet Downloader Manager (IDM) Crack 6.42 Build 41

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 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?
  • 7. 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
  • 8. 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
  • 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 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.
  • 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 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
  • 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) }