Monad and Algebraic Design in
Functional Programming
SOLID Design Pattern Principles
• Single Responsibility Principle
• Open/Closed Principle
• Liskov Substitution Principle
• Interface Segregation Principle
• Dependency Inversion Principle
Strategy Pattern
Strategy Pattern
Strategy Pattern
Strategy Pattern
Composition over Inheritance
(in OOP)
Algebraic Design
if S (system of axioms) → then Q (set of theorems)
Functor
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
def lift[A, B](f: A => B): F[A] => F[B] = map(_)(f)
def mapply[A, B](a: A)(f: F[A => B]): F[B] = map(f)((ff: A => B) => ff(a))
def fproduct[A, B](fa: F[A])(f: A => B): F[(A, B)] = map(fa)(a => (a, f(a)))
}
// Functor Law
// identity element
map(fa)(identity) == fa // must be true
What is Monad
Option, Either, List, Par, State and something like that...
What is Monad: Part 1 - flatMap
trait Monad[F[_]] extends Functor[F] {
def pure[A](x: => A): F[A]
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
def map[A, B](fa: F[A])(f: A => B): F[B] = flatMap(fa)((a: A) => pure(f(a)))
}
// Monad Laws
// a. associated law
flatMap(flatMap(fa)(f))(g) == flatMap(fa)(b => flatMap(f(b))(g))
// b. identity element
flatMap(fa)(unit) == fa
flatMap(unit(a))(f) = f(a)
What is Monad: Part 2 - compose of Kleisli Arrow
type Kleisli[F[_], A, B] = A => F[B]
trait Monad[F[_]] extends Functor[F] {
def pure[A](x: => A): F[A]
def compose[A, B](k1: Kleisli[F, A, B], k2: Kleisli[F, B, C]): Kleisli[F, A, C]
// def compose(k1: A => F[B], k2: B => F[C]): A => F[C]
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] = compose(() => fa, f)
}
// Monad Laws
// a. associated law
compose(compose(f, g), h) == compose(f, compose(g, h))
// b. identity element
compose(f, pure) == f
compose(pure, f) == f
What is Monad: by definition
• pure & flatMap or pure & compose
• associated law and identity elements
What is Functor
What is Applicative
What is Monad
Why Monad
A monad is a control mechanism for sequencing computations
Why Monad: Railway Oriented Programming
def validate(a: A): Either[Exception, A] = ???
def update(a: A): Either[Exception, B] = ???
def send(b: B): Either[Exception, Response] = ???
val resE: Either[Exception, Response] = for {
va <- validate(a)
b <- update(va)
res <- send(b)
} yield res
Sample: Type Representation of Monomorphism &
Epimorphism
type Mon[A, B] = Kleisli[Some, A, B]
type Epi[A, B] = Kleisli[Option, A, B]
Isomorphism
type Iso[A, B] = A => B
Monomorphism
type Mon[A, B] = Kleisli[Some, A, B]
Epimorphism
type Epi[A, B] = Kleisli[Option, A, B]

Monad and Algebraic Design in Functional Programming

  • 1.
    Monad and AlgebraicDesign in Functional Programming
  • 2.
    SOLID Design PatternPrinciples • Single Responsibility Principle • Open/Closed Principle • Liskov Substitution Principle • Interface Segregation Principle • Dependency Inversion Principle
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
    Algebraic Design if S(system of axioms) → then Q (set of theorems)
  • 9.
    Functor trait Functor[F[_]] { defmap[A, B](fa: F[A])(f: A => B): F[B] def lift[A, B](f: A => B): F[A] => F[B] = map(_)(f) def mapply[A, B](a: A)(f: F[A => B]): F[B] = map(f)((ff: A => B) => ff(a)) def fproduct[A, B](fa: F[A])(f: A => B): F[(A, B)] = map(fa)(a => (a, f(a))) } // Functor Law // identity element map(fa)(identity) == fa // must be true
  • 10.
    What is Monad Option,Either, List, Par, State and something like that...
  • 11.
    What is Monad:Part 1 - flatMap trait Monad[F[_]] extends Functor[F] { def pure[A](x: => A): F[A] def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] def map[A, B](fa: F[A])(f: A => B): F[B] = flatMap(fa)((a: A) => pure(f(a))) } // Monad Laws // a. associated law flatMap(flatMap(fa)(f))(g) == flatMap(fa)(b => flatMap(f(b))(g)) // b. identity element flatMap(fa)(unit) == fa flatMap(unit(a))(f) = f(a)
  • 12.
    What is Monad:Part 2 - compose of Kleisli Arrow type Kleisli[F[_], A, B] = A => F[B] trait Monad[F[_]] extends Functor[F] { def pure[A](x: => A): F[A] def compose[A, B](k1: Kleisli[F, A, B], k2: Kleisli[F, B, C]): Kleisli[F, A, C] // def compose(k1: A => F[B], k2: B => F[C]): A => F[C] def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] = compose(() => fa, f) } // Monad Laws // a. associated law compose(compose(f, g), h) == compose(f, compose(g, h)) // b. identity element compose(f, pure) == f compose(pure, f) == f
  • 13.
    What is Monad:by definition • pure & flatMap or pure & compose • associated law and identity elements
  • 14.
  • 15.
  • 16.
  • 17.
    Why Monad A monadis a control mechanism for sequencing computations
  • 18.
    Why Monad: RailwayOriented Programming def validate(a: A): Either[Exception, A] = ??? def update(a: A): Either[Exception, B] = ??? def send(b: B): Either[Exception, Response] = ??? val resE: Either[Exception, Response] = for { va <- validate(a) b <- update(va) res <- send(b) } yield res
  • 19.
    Sample: Type Representationof Monomorphism & Epimorphism type Mon[A, B] = Kleisli[Some, A, B] type Epi[A, B] = Kleisli[Option, A, B]
  • 20.
  • 21.
    Monomorphism type Mon[A, B]= Kleisli[Some, A, B]
  • 22.
    Epimorphism type Epi[A, B]= Kleisli[Option, A, B]