SlideShare a Scribd company logo
1 of 170
Download to read offline
“Going bananas with
recursion schemes for
fixed point data types”
Software
Engineering
Software engineering
Elegance of Functional Programming
Recursion
Recursion Schemes
Recursion Schemes
●
●
Boring
Academia Alert!
Can we actually
can Build some
Stuff?
Real world application
Real world application
Real world application
Recursive Structures are common
Recursive Structures are common
●
○
■
■
○
■
■
Recursive Structures are common
●
○
■
■
○
■
■
●
○
○
○
Recursive Structures are common
●
○
■
■
○
■
■
●
○
○
○
●
Expressions!
Expressions!
Expressions!
Expressions!
Expressions!
Expressions!
Expressions!
Expressions!
Expressions!
Expressions!
Square
Sum
Square
10
Multiply
10 10
data Exp = IntVal Int |
DecVal Double |
Sum Exp Exp |
Multiply Exp Exp |
Divide Exp Exp |
Square Exp
data Exp = IntVal Int |
DecVal Double |
Sum Exp Exp |
Multiply Exp Exp |
Divide Exp Exp |
Square Exp
sealed trait Exp
final case class IntValue(v: Int) extends Exp
final case class DecValue(v: Double) extends Exp
final case class Sum(exp1: Exp, exp2: Exp) extends Exp
final case class Multiply(exp1: Exp, exp2: Exp) extends Exp
final case class Divide(exp1: Exp, exp2: Exp) extends Exp
final case class Square(exp: Exp) extends Exp
data Exp = IntVal Int |
DecVal Double |
Sum Exp Exp |
Multiply Exp Exp |
Divide Exp Exp |
Square Exp
sealed trait Exp
final case class IntValue(v: Int) extends Exp
final case class DecValue(v: Double) extends Exp
final case class Sum(exp1: Exp, exp2: Exp) extends Exp
final case class Multiply(exp1: Exp, exp2: Exp) extends Exp
final case class Divide(exp1: Exp, exp2: Exp) extends Exp
final case class Square(exp: Exp) extends Exp
sealed trait Exp
final case class IntValue(v: Int) extends Exp
final case class DecValue(v: Double) extends Exp
final case class Sum(exp1: Exp, exp2: Exp) extends Exp
final case class Multiply(exp1: Exp, exp2: Exp) extends Exp
final case class Divide(exp1: Exp, exp2: Exp) extends Exp
final case class Square(exp: Exp) extends Exp
val evaluate: Exp => Double =
sealed trait Exp
final case class IntValue(v: Int) extends Exp
final case class DecValue(v: Double) extends Exp
final case class Sum(exp1: Exp, exp2: Exp) extends Exp
final case class Multiply(exp1: Exp, exp2: Exp) extends Exp
final case class Divide(exp1: Exp, exp2: Exp) extends Exp
final case class Square(exp: Exp) extends Exp
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2)
}
sealed trait Exp
final case class IntValue(v: Int) extends Exp
final case class DecValue(v: Double) extends Exp
final case class Sum(exp1: Exp, exp2: Exp) extends Exp
final case class Multiply(exp1: Exp, exp2: Exp) extends Exp
final case class Divide(exp1: Exp, exp2: Exp) extends Exp
final case class Square(exp: Exp) extends Exp
val mkString: Exp => String = {
case IntValue(v) => v.toString
case DecValue(v) => v.toString
case Sum(exp1, exp2) => s"( ${mkStr(exp1)} + ${mkStr(exp2)})"
case Multiply(exp1, exp2) => s"( ${mkStr(exp1)} * ${mkStr(exp2)})"
case Square(exp) => s"(${mkStr(exp)})^2"
case Divide(exp1, exp2) => s"( ${mkStr(exp1)} / ${mkStr(exp2)})"
}
sealed trait Exp
final case class IntValue(v: Int) extends Exp
final case class DecValue(v: Double) extends Exp
final case class Sum(exp1: Exp, exp2: Exp) extends Exp
final case class Multiply(exp1: Exp, exp2: Exp) extends Exp
final case class Divide(exp1: Exp, exp2: Exp) extends Exp
final case class Square(exp: Exp) extends Exp
val optimize: Exp => Exp = {
case Multiply(exp1, exp2)
if(exp1 == exp2) => Square(optimize(exp1))
sealed trait Exp
final case class IntValue(v: Int) extends Exp
final case class DecValue(v: Double) extends Exp
final case class Sum(exp1: Exp, exp2: Exp) extends Exp
final case class Multiply(exp1: Exp, exp2: Exp) extends Exp
final case class Divide(exp1: Exp, exp2: Exp) extends Exp
final case class Square(exp: Exp) extends Exp
val optimize: Exp => Exp = {
case Multiply(exp1, exp2)
if(exp1 == exp2) => Square(optimize(exp1))
case IntValue(v) => IntValue(v)
case DecValue(v) => DecValue(v)
case Sum(exp1, exp2) => Sum(optimize(exp1), optimize(exp2))
case Multiply(exp1, exp2) => Multiply(optimize(exp1), optimize(exp2))
case Square(exp) => Square(optimize(exp))
case Divide(exp1, exp2) => Divide(optimize(exp1), optimize(exp2))
}
sealed trait Exp
final case class IntValue(v: Int) extends Exp
final case class DecValue(v: Double) extends Exp
final case class Sum(exp1: Exp, exp2: Exp) extends Exp
final case class Multiply(exp1: Exp, exp2: Exp) extends Exp
final case class Divide(exp1: Exp, exp2: Exp) extends Exp
final case class Square(exp: Exp) extends Exp
val optimize: Exp => Exp = {
case Multiply(exp1, exp2)
if(exp1 == exp2) => Square(optimize(exp1))
case IntValue(v) => IntValue(v)
case DecValue(v) => DecValue(v)
case Sum(exp1, exp2) => Sum(optimize(exp1), optimize(exp2))
case Multiply(exp1, exp2) => Multiply(exp1, optimize(exp2))
case Square(exp) => Square(optimize(exp))
case Divide(exp1, exp2) => Divide(optimize(exp1), optimize(exp2))
}
sealed trait Exp
final case class IntValue(v: Int) extends Exp
final case class DecValue(v: Double) extends Exp
final case class Sum(exp1: Exp, exp2: Exp) extends Exp
final case class Multiply(exp1: Exp, exp2: Exp) extends Exp
final case class Divide(exp1: Exp, exp2: Exp) extends Exp
final case class Square(exp: Exp) extends Exp
val optimize: Exp => Exp = {
case Multiply(exp1, exp2)
if(exp1 == exp2) => Square(optimize(exp1))
case IntValue(v) => optimize(IntValue(v))
case DecValue(v) => optimize(DecValue(v))
case Sum(exp1, exp2) => Sum(optimize(exp1), optimize(exp2))
case Multiply(exp1, exp2) => Multiply(optimize(exp1), optimize(exp2))
case Square(exp) => Square(optimize(exp))
case Divide(exp1, exp2) => Divide(optimize(exp1), optimize(exp2))
}
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val mkString: Exp => String = {
case IntValue(v) => v.toString
case DecValue(v) => v.toString
case Sum(exp1, exp2) =>
s"(${mkStr(exp1)} + ${mkStr(exp2)})"
case Multiply(exp1, exp2) =>
s"(${mkStr(exp1)} * ${mkStr(exp2)})"
case Square(exp) =>
s"(${mkStr(exp)})^2"
case Divide(exp1, exp2) =>
s"( ${mkStr(exp1)} / ${mkStr(exp2)})"
} val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
sealed trait Exp
final case class IntValue(v: Int) extends Exp
final case class DecValue(v: Double) extends Exp
final case class Sum(exp1: Exp, exp2: Exp) extends Exp
final case class Multiply(exp1: Exp, exp2: Exp) extends Exp
final case class Divide(exp1: Exp, exp2: Exp) extends Exp
final case class Square(exp: Exp) extends Exp
sealed trait Exp
final case class IntValue(v: Int) extends Exp
final case class DecValue(v: Double) extends Exp
final case class Sum(exp1: Exp, exp2: Exp) extends Exp
final case class Multiply(exp1: Exp, exp2: Exp) extends Exp
final case class Divide(exp1: Exp, exp2: Exp) extends Exp
final case class Square(exp: Exp) extends Exp
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp1: Exp[?] =
Sum[?](IntValue[?](10),
IntValue[?](5))
)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp1: Exp[?] =
Sum[?](IntValue[Unit](10),
IntValue[Unit](5))
)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp1: Exp[?] =
Sum[?](IntValue[Unit](10),
IntValue[Unit](5))
)
Exp[Unit]
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp1: Exp[?] =
Sum[?](IntValue[Unit](10),
IntValue[Unit](5))
)
Exp[Unit]
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp1: Exp[?] =
Sum[?](IntValue[Unit](10),
IntValue[Unit](5))
)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp1: Exp[?] =
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp2: Exp =
Divide(
DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
val exp2: Exp[?] =
Divide[?](
DecValue[?](5.2),
Sum[?](IntValue[?](10),
IntValue[?](5))
)
)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp2: Exp =
Divide(
DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
val exp2: Exp[?] =
Divide[?](
DecValue[?](5.2),
Sum[?](IntValue[Unit](10),
IntValue[Unit](5))
)
)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp2: Exp =
Divide(
DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
val exp2: Exp[?] =
Divide[?](
DecValue[?](5.2),
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp2: Exp =
Divide(
DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
val exp2: Exp[?] =
Divide[?](
DecValue[Exp[Unit]](5.2),
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp2: Exp =
Divide(
DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
val exp2: Exp[?] =
Divide[Exp[Exp[Unit]]](
DecValue[Exp[Unit]](5.2),
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp2: Exp =
Divide(
DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
val exp2: Exp[Exp[Exp[Unit]]] =
Divide[Exp[Exp[Unit]]](
DecValue[Exp[Unit]](5.2),
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp2: Exp =
Divide(
DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
val exp2: Exp[Exp[Exp[Unit]]] =
Divide[Exp[Exp[Unit]]](
DecValue[Exp[Unit]](5.2),
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp2: Exp =
Divide(
DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
val exp2: Exp[Exp[Exp[Unit]]] =
Divide[Exp[Exp[Unit]]](
DecValue[Exp[Unit]](5.2),
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp2: Exp =
Divide(
DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
val exp3: Exp = from(input)
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
val exp2: Exp[Exp[Exp[Unit]]] =
Divide[Exp[Exp[Unit]]](
DecValue[Exp[Unit]](5.2),
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
)
val exp3: Exp[?] = from(input)
sealed trait Exp[A]
final case class IntValue[A](v: Int) extends Exp[A]
final case class DecValue[A](v: Double) extends Exp[A]
final case class Sum[A](exp1: A, exp2: A) extends Exp[A]
final case class Multiply[A](exp1: A, exp2: A) extends Exp[A]
final case class Divide[A](exp1: A, exp2: A) extends Exp[A]
final case class Square[A](exp: A) extends Exp[A]
val exp1: Exp =
Sum(IntValue(10),
IntValue(5))
)
val exp2: Exp =
Divide(
DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
val exp3: Exp = from(input)
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
val exp2: Exp[Exp[Exp[Unit]]] =
Divide[Exp[Exp[Unit]]](
DecValue[Exp[Unit]](5.2),
Sum[Exp[Unit]](IntValue[Unit](10),
IntValue[Unit](5))
)
)
val exp3: Exp[Exp[Exp[Exp[Exp[Exp[Exp[Exp[Exp[Ex
Introducing:
fix point data
types!
Fix
case class Fix[F[_]](unFix: F[Fix[F]])
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](
IntValue[Unit](10),
IntValue[Unit](5)
)
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](
Fix(IntValue[Unit](10)),
Fix(IntValue[Unit](5))
)
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Exp[Exp[Unit]] =
Sum[Exp[Unit]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5))
)
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Exp[Exp[Unit]] =
Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5))
)
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Exp[Exp[Unit]] =
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5))
))
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Fix[Exp] =
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5))
))
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Fix[Exp] =
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5))
))
val exp2: Exp[Exp[Exp[Unit]]] =
Divide[Exp[Exp[Unit]]](
DecValue[Exp[Unit]](5.2),
Sum[Exp[Unit]](
IntValue[Unit](10),
IntValue[Unit](5))
)
)
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Fix[Exp] =
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5))
))
val exp2: Exp[Exp[Exp[Unit]]] =
Divide[Exp[Exp[Unit]]](
DecValue[Exp[Unit]](5.2),
Sum[Exp[Unit]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5)))
)
)
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Fix[Exp] =
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5))
))
val exp2: Exp[Exp[Exp[Unit]]] =
Divide[Exp[Exp[Unit]]](
DecValue[Exp[Unit]](5.2),
Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5)))
)
)
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Fix[Exp] =
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5))
))
val exp2: Exp[Exp[Exp[Unit]]] =
Divide[Exp[Exp[Unit]]](
Fix(DecValue[Fix[Exp]](5.2)),
Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5)))
)
)
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Fix[Exp] =
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5))
))
val exp2: Exp[Exp[Exp[Unit]]] =
Divide[Exp[Exp[Unit]]](
Fix(DecValue[Fix[Exp]](5.2)),
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5)))
))
)
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Fix[Exp] =
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5))
))
val exp2: Exp[Exp[Exp[Unit]]] =
Fix(Divide[Fix[Exp]](
Fix(DecValue[Fix[Exp]](5.2)),
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5)))
))
))
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Fix[Exp] =
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5))
))
val exp2: Fix[Exp] =
Fix(Divide[Fix[Exp]](
Fix(DecValue[Fix[Exp]](5.2)),
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5)))
))
))
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Fix[Exp] =
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5))
))
val exp2: Fix[Exp] =
Fix(Divide[Fix[Exp]](
Fix(DecValue[Fix[Exp]](5.2)),
Fix(Sum[Fix[Exp]](
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](5)))
))
))
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Fix[Exp] =
Fix(Sum(
Fix(IntValue(10)),
Fix(IntValue(5))
))
val exp2: Fix[Exp] =
Fix(Divide(
Fix(DecValue(5.2)),
Fix(Sum(
Fix(IntValue(10)),
Fix(IntValue(5))
))
))
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Fix[Exp] =
Fix(Sum(
Fix(IntValue(10)),
Fix(IntValue(5))
))
val exp2: Fix[Exp] =
Fix(Divide(
Fix(DecValue(5.2)),
Fix(Sum(
Fix(IntValue(10)),
Fix(IntValue(5))
))
))
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Fix[Exp] =
Fix(Sum(
Fix(IntValue(10)),
Fix(IntValue(5))
))
val exp2: Fix[Exp] =
Fix(Divide(
Fix(DecValue(5.2)),
Fix(Sum(
Fix(IntValue(10)),
Fix(IntValue(5))
))
))
case class Fix[F[_]](unFix: F[Fix[F]])
val exp1: Fix[Exp] =
Fix(Sum(
Fix(IntValue(10)),
Fix(IntValue(5))
))
val exp2: Fix[Exp] =
Fix(Divide(
Fix(DecValue(5.2)),
Fix(Sum(
Fix(IntValue(10)),
Fix(IntValue(5))
))
))
val exp3: Fix[Exp] = from(input)
val evaluate: Exp => Double = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(exp1, exp2) =>
evaluate(exp1) + evaluate(exp2)
case Multiply(exp1, exp2) =>
evaluate(exp1) * evaluate(exp2)
case Square(exp) =>
val v = evaluate(exp)
v * v
case Divide(exp1, exp2) =>
evaluate(exp1) / evaluate(exp2)
}
val exp = Multiply(
Sum(IntValue(10),
DecValue(2.5)),
Divide(DecValue(5.2),
Sum(IntValue(10),
IntValue(5))
)
)
Multiply
Sum Divide
Int(10) Dec(2.5) Dec(5.2) Sum
Int(10) Int(5)
Need something
that will
traverse the
structure…
Catamorphism
Missing Ingredients
Functor 101
Functor 101
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
Functor 101
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
def foo[A[_], T](a: A[T])
Functor 101
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
def foo[A[_], T](a: A[T])(trans: T => Int)
Functor 101
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
def foo[A[_], T](a: A[T])(trans: T => Int): A[Int] = ???
Functor 101
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
def foo[A[_] : Functor, T](a: A[T])(trans: T => Int): A[Int] = ???
Functor 101
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
def foo[A[_] : Functor, T](a: A[T])(trans: T => Int): A[Int] = a.map(trans)
Functor 101
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
def foo[A[_] : Functor, T](a: A[T])(trans: T => Int): A[Int] = a.map(trans)
case class Container[T](t: T)
val r: Container[Int] =
foo[Container, String](Container("bar"))(str => str.length)
Functor 101
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
def foo[A[_] : Functor, T](a: A[T])(trans: T => Int): A[Int] = a.map(trans)
implicit val functor: Functor[Container] = new Functor[Container] {
def map[A, B](c: Container[A])(f: A => B): Container[B] = Container(f(c.t))
}
case class Container[T](t: T)
val r: Container[Int] =
foo[Container, String](Container("bar"))(str => str.length)
sealed trait Exp
final case class IntValue(v: Int) extends Exp
final case class DecValue(v: Double) extends Exp
final case class Sum(exp1: Exp, exp2: Exp) extends Exp
final case class Multiply(exp1: Exp, exp2: Exp) extends Exp
final case class Divide(exp1: Exp, exp2: Exp) extends Exp
final case class Square(exp: Exp) extends Exp
implicit val functor: Functor[Exp] = new Functor[Exp] {
def map[A, B](exp: Exp[A])(f: A => B): Exp[B] =
sealed trait Exp
final case class IntValue(v: Int) extends Exp
final case class DecValue(v: Double) extends Exp
final case class Sum(exp1: Exp, exp2: Exp) extends Exp
final case class Multiply(exp1: Exp, exp2: Exp) extends Exp
final case class Divide(exp1: Exp, exp2: Exp) extends Exp
final case class Square(exp: Exp) extends Exp
implicit val functor: Functor[Exp] = new Functor[Exp] {
def map[A, B](exp: Exp[A])(f: A => B): Exp[B] = exp match {
case Sum(a1, a2) => Sum(f(a1), f(a2))
case Multiply(a1, a2) => Multiply(f(a1), f(a2))
case Divide(a1, a2) => Divide(f(a1), f(a2))
case Square(a) => Square(f(a))
case IntValue(v) => IntValue(v)
case DecValue(v) => DecValue(v)
}
}
Missing Ingredients
Missing Ingredients
Missing Ingredients
F-algebra
type Algebra[F[_], A] = F[A] => A
type Algebra[F[_], A] = F[A] => A
val evaluate: Algebra[Exp, Double] = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(a1, a2) => a1 + a2
case Multiply(a1, a2) => a1 * a2
case Square(a) => a * a
case Divide(a1, a2) => a1 / a2
}
type Algebra[F[_], A] = F[A] => A
val evaluate: Algebra[Exp, Double] = {
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(a1, a2) => a1 + a2
case Multiply(a1, a2) => a1 * a2
case Square(a) => a * a
case Divide(a1, a2) => a1 / a2
}
val mkStr: Algebra[Exp, String] = {
case IntValue(v) => v.toString
case DecValue(v) => v.toString
case Sum(a1, a2) => s"($a1 + $a2)"
case Multiply(a1, a2) => s"($a1 + $a2)"
case Square(a) => s"($a)^2"
case Divide(a1, a2) => s"($a1 + $a2)"
}
val evaluate: Algebra[Exp, Double] = { // Exp[Double] => Double
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(a1, a2) => a1 + a2
case Multiply(a1, a2) => a1 * a2
case Square(a) => a * a
case Divide(a1, a2) => a1 / a2
}
val evaluate: Algebra[Exp, Double] = { // Exp[Double] => Double
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(a1, a2) => a1 + a2
case Multiply(a1, a2) => a1 * a2
case Square(a) => a * a
case Divide(a1, a2) => a1 / a2
}
val exp2: Fix[Exp] = Fix(Divide(
Fix(DecValue(5.2)),
Fix(Sum(
Fix(IntValue(10)),
Fix(IntValue(5))
))
))
val evaluate: Algebra[Exp, Double] = { // Exp[Double] => Double
case IntValue(v) => v.toDouble
case DecValue(v) => v
case Sum(a1, a2) => a1 + a2
case Multiply(a1, a2) => a1 * a2
case Square(a) => a * a
case Divide(a1, a2) => a1 / a2
}
val exp2: Fix[Exp] = Fix(Divide(
Fix(DecValue(5.2)),
Fix(Sum(
Fix(IntValue(10)),
Fix(IntValue(5))
))
))
> exp2.cata(evaluate)
0.3466666666666667
val mkStr: Algebra[Exp, String] = { // Exp[Double] => Double
case IntValue(v) => v.toString
case DecValue(v) => v.toString
case Sum(a1, a2) => s"($a1 + $a2)"
case Multiply(a1, a2) => s"($a1 + $a2)"
case Square(a) => s"($a)^2"
case Divide(a1, a2) => s"($a1 + $a2)"
}
val mkStr: Algebra[Exp, String] = { // Exp[Double] => Double
case IntValue(v) => v.toString
case DecValue(v) => v.toString
case Sum(a1, a2) => s"($a1 + $a2)"
case Multiply(a1, a2) => s"($a1 + $a2)"
case Square(a) => s"($a)^2"
case Divide(a1, a2) => s"($a1 + $a2)"
}
val exp2: Fix[Exp] = Fix(Divide(
Fix(DecValue(5.2)),
Fix(Sum(
Fix(IntValue(10)),
Fix(IntValue(5))
))
))
val mkStr: Algebra[Exp, String] = { // Exp[Double] => Double
case IntValue(v) => v.toString
case DecValue(v) => v.toString
case Sum(a1, a2) => s"($a1 + $a2)"
case Multiply(a1, a2) => s"($a1 + $a2)"
case Square(a) => s"($a)^2"
case Divide(a1, a2) => s"($a1 + $a2)"
}
val exp2: Fix[Exp] = Fix(Divide(
Fix(DecValue(5.2)),
Fix(Sum(
Fix(IntValue(10)),
Fix(IntValue(5))
))
))
> exp2.cata(mkStr)
(5.2 + (10 + 5))
val optimize: Exp => Exp = {
case Multiply(exp1, exp2)
if(exp1 == exp2) => Square(optimize(exp1))
case IntValue(v) => IntValue(v)
case DecValue(v) => DecValue(v)
case Sum(exp1, exp2) => Sum(optimize(exp1), optimize(exp2))
case Multiply(exp1, exp2) => Multiply(optimize(exp1), optimize(exp2))
case Square(exp) => Square(optimize(exp))
case Divide(exp1, exp2) => Divide(optimize(exp1), optimize(exp2))
}
val optimize: Exp => Exp = {
case Multiply(exp1, exp2)
if(exp1 == exp2) => Square(optimize(exp1))
case IntValue(v) => IntValue(v)
case DecValue(v) => DecValue(v)
case Sum(exp1, exp2) => Sum(optimize(exp1), optimize(exp2))
case Multiply(exp1, exp2) => Multiply(optimize(exp1), optimize(exp2))
case Square(exp) => Square(optimize(exp))
case Divide(exp1, exp2) => Divide(optimize(exp1), optimize(exp2))
}
val optimize: Algebra[Exp, Fix[Exp]] = { // Exp[Fix[Exp]] => Fix[Exp]
case Multiply(Fix(a1), Fix(a2)) if(a1 == a2) => Fix(Square(Fix(a1)))
case other => Fix(other)
}
val optimize: Algebra[Exp, Fix[Exp]] = { // Exp[Fix[Exp]] => Fix[Exp]
case Multiply(Fix(a1), Fix(a2)) if(a1 == a2) => Fix(Square(Fix(a1)))
case other => Fix(other)
}
val optimize: Algebra[Exp, Fix[Exp]] = { // Exp[Fix[Exp]] => Fix[Exp]
case Multiply(Fix(a1), Fix(a2)) if(a1 == a2) => Fix(Square(Fix(a1)))
case other => Fix(other)
}
val aTimesAExp: Fix[Exp] =
Fix(Multiply(
Fix(Sum(
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](20))
)),
Fix(Sum(
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](20))
))
))
val optimize: Algebra[Exp, Fix[Exp]] = { // Exp[Fix[Exp]] => Fix[Exp]
case Multiply(Fix(a1), Fix(a2)) if(a1 == a2) => Fix(Square(Fix(a1)))
case other => Fix(other)
}
val aTimesAExp: Fix[Exp] =
Fix(Multiply(
Fix(Sum(
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](20))
)),
Fix(Sum(
Fix(IntValue[Fix[Exp]](10)),
Fix(IntValue[Fix[Exp]](20))
))
))
> aTimesAExp.cata(optimize)
Fix(Square(Fix(Sum(Fix(IntValue(10)),Fix(IntValue(20))))))
ZOO of
morphisims
Anamorphism
●
Anamorphism
●
●
Anamorphism
●
●
●
Anamorphism
●
●
●
●
●
type Coalgebra[F[_], A] = A => F[A]
type Coalgebra[F[_], A] = A => F[A]
val divisors: Coalgebra[Exp, Int] = {
case n if(n % 2 == 0 && n != 2) => Multiply(2, n / 2)
case n => IntValue(n)
}
type Coalgebra[F[_], A] = A => F[A]
val divisors: Coalgebra[Exp, Int] = {
case n if(n % 2 == 0 && n != 2) => Multiply(2, n / 2)
case n => IntValue(n)
}
> 12.ana[Fix, Exp](divisors)
type Coalgebra[F[_], A] = A => F[A]
val divisors: Coalgebra[Exp, Int] = {
case n if(n % 2 == 0 && n != 2) => Multiply(2, n / 2)
case n => IntValue(n)
}
> 12.ana[Fix, Exp](divisors)
Fix(Multiply(Fix(IntValue(2)),Fix(Multiply(Fix(IntValue(2)),Fix(Multiply(Fix(IntVal
ue(2)),Fix(IntValue(7))))))))
Hylomorphism
Hylomorphism
●
Hylomorphism
●
●
Hylomorphism
●
●
●
Hylomorphism
●
●
●
Hylomorphism
●
●
●
val divisors: Coalgebra[Exp, Int] = { … } // Double => Exp[Double]
val evaluate: Algebra[Exp, Double] = { … } // Exp[Double] => Double
val divisors: Coalgebra[Exp, Int] = { … } // Double => Exp[Double]
val evaluate: Algebra[Exp, Double] = { … } // Exp[Double] => Double
describe("divisors") {
it("once evaluated will give initial value") {
forAll(positiveInt) { n =>
n.ana(divisiors).cata(evaluate) shouldEqual(n)
}
}
val divisors: Coalgebra[Exp, Int] = { … } // Double => Exp[Double]
val evaluate: Algebra[Exp, Double] = { … } // Exp[Double] => Double
describe("divisors") {
it("once evaluated will give initial value") {
forAll(positiveInt) { n =>
n.hylo(evaluate, divisors) shouldEqual(n)
}
}
What else?
To sum it up
To sum it up
●
To sum it up
●
●
To sum it up
●
●
●
○
○
To sum it up
●
●
●
○
○
●
To sum it up
●
●
●
○
○
●
●
To sum it up
●
●
●
○
○
●
●
●
References
Pawel Szulc
Pawel Szulc
@rabbitonweb
Pawel Szulc
@rabbitonweb
paul.szulc@gmail.com
Pawel Szulc
@rabbitonweb
paul.szulc@gmail.com
http://rabbitonweb.com

More Related Content

What's hot

Rcommands-for those who interested in R.
Rcommands-for those who interested in R.Rcommands-for those who interested in R.
Rcommands-for those who interested in R.Dr. Volkan OBAN
 
Calculus 08 techniques_of_integration
Calculus 08 techniques_of_integrationCalculus 08 techniques_of_integration
Calculus 08 techniques_of_integrationtutulk
 
Google Go For Ruby Hackers
Google Go For Ruby HackersGoogle Go For Ruby Hackers
Google Go For Ruby HackersEleanor McHugh
 
Declarative Thinking, Declarative Practice
Declarative Thinking, Declarative PracticeDeclarative Thinking, Declarative Practice
Declarative Thinking, Declarative PracticeKevlin Henney
 
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...Codemotion
 
R reference card
R reference cardR reference card
R reference cardHesher Shih
 
TensorFlow in Practice
TensorFlow in PracticeTensorFlow in Practice
TensorFlow in Practiceindico data
 
Gentlest Introduction to Tensorflow - Part 2
Gentlest Introduction to Tensorflow - Part 2Gentlest Introduction to Tensorflow - Part 2
Gentlest Introduction to Tensorflow - Part 2Khor SoonHin
 
Programming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAYProgramming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAYvikram mahendra
 
Gentlest Introduction to Tensorflow - Part 3
Gentlest Introduction to Tensorflow - Part 3Gentlest Introduction to Tensorflow - Part 3
Gentlest Introduction to Tensorflow - Part 3Khor SoonHin
 
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...PROIDEA
 
Nikolay Shilov. CSEDays 3
Nikolay Shilov. CSEDays 3Nikolay Shilov. CSEDays 3
Nikolay Shilov. CSEDays 3LiloSEA
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patternsleague
 
R short-refcard
R short-refcardR short-refcard
R short-refcardconline
 
Gentlest Introduction to Tensorflow
Gentlest Introduction to TensorflowGentlest Introduction to Tensorflow
Gentlest Introduction to TensorflowKhor SoonHin
 

What's hot (17)

Rcommands-for those who interested in R.
Rcommands-for those who interested in R.Rcommands-for those who interested in R.
Rcommands-for those who interested in R.
 
FYP Final Presentation
FYP Final PresentationFYP Final Presentation
FYP Final Presentation
 
Calculus 08 techniques_of_integration
Calculus 08 techniques_of_integrationCalculus 08 techniques_of_integration
Calculus 08 techniques_of_integration
 
Google Go For Ruby Hackers
Google Go For Ruby HackersGoogle Go For Ruby Hackers
Google Go For Ruby Hackers
 
Declarative Thinking, Declarative Practice
Declarative Thinking, Declarative PracticeDeclarative Thinking, Declarative Practice
Declarative Thinking, Declarative Practice
 
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
 
R reference card
R reference cardR reference card
R reference card
 
TensorFlow in Practice
TensorFlow in PracticeTensorFlow in Practice
TensorFlow in Practice
 
Gentlest Introduction to Tensorflow - Part 2
Gentlest Introduction to Tensorflow - Part 2Gentlest Introduction to Tensorflow - Part 2
Gentlest Introduction to Tensorflow - Part 2
 
Programming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAYProgramming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAY
 
Gentlest Introduction to Tensorflow - Part 3
Gentlest Introduction to Tensorflow - Part 3Gentlest Introduction to Tensorflow - Part 3
Gentlest Introduction to Tensorflow - Part 3
 
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
 
Nikolay Shilov. CSEDays 3
Nikolay Shilov. CSEDays 3Nikolay Shilov. CSEDays 3
Nikolay Shilov. CSEDays 3
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
R short-refcard
R short-refcardR short-refcard
R short-refcard
 
Gentlest Introduction to Tensorflow
Gentlest Introduction to TensorflowGentlest Introduction to Tensorflow
Gentlest Introduction to Tensorflow
 
R Refcard
R RefcardR Refcard
R Refcard
 

Viewers also liked

Make your programs Free
Make your programs FreeMake your programs Free
Make your programs FreePawel Szulc
 
Reducing Boilerplate and Combining Effects: A Monad Transformer Example
Reducing Boilerplate and Combining Effects: A Monad Transformer ExampleReducing Boilerplate and Combining Effects: A Monad Transformer Example
Reducing Boilerplate and Combining Effects: A Monad Transformer ExampleConnie Chen
 
The cats toolbox a quick tour of some basic typeclasses
The cats toolbox  a quick tour of some basic typeclassesThe cats toolbox  a quick tour of some basic typeclasses
The cats toolbox a quick tour of some basic typeclassesPawel Szulc
 
Real world gobbledygook
Real world gobbledygookReal world gobbledygook
Real world gobbledygookPawel Szulc
 
Introduction to type classes in 30 min
Introduction to type classes in 30 minIntroduction to type classes in 30 min
Introduction to type classes in 30 minPawel Szulc
 
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...John De Goes
 
Getting Started with PureScript
Getting Started with PureScriptGetting Started with PureScript
Getting Started with PureScriptJohn De Goes
 
Apache spark when things go wrong
Apache spark   when things go wrongApache spark   when things go wrong
Apache spark when things go wrongPawel Szulc
 
Introduction to type classes
Introduction to type classesIntroduction to type classes
Introduction to type classesPawel Szulc
 
FP is coming... le 19/05/2016
FP is coming... le 19/05/2016FP is coming... le 19/05/2016
FP is coming... le 19/05/2016Loïc Knuchel
 
Writing your own RDD for fun and profit
Writing your own RDD for fun and profitWriting your own RDD for fun and profit
Writing your own RDD for fun and profitPawel Szulc
 
Implementing pattern-matching in JavaScript (short version)
Implementing pattern-matching in JavaScript (short version)Implementing pattern-matching in JavaScript (short version)
Implementing pattern-matching in JavaScript (short version)François-Guillaume Ribreau
 
Functional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heavenFunctional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heavenPawel Szulc
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and FutureJohn De Goes
 
Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!John De Goes
 
Apache spark workshop
Apache spark workshopApache spark workshop
Apache spark workshopPawel Szulc
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free MonadsJohn De Goes
 

Viewers also liked (20)

Make your programs Free
Make your programs FreeMake your programs Free
Make your programs Free
 
Reducing Boilerplate and Combining Effects: A Monad Transformer Example
Reducing Boilerplate and Combining Effects: A Monad Transformer ExampleReducing Boilerplate and Combining Effects: A Monad Transformer Example
Reducing Boilerplate and Combining Effects: A Monad Transformer Example
 
The cats toolbox a quick tour of some basic typeclasses
The cats toolbox  a quick tour of some basic typeclassesThe cats toolbox  a quick tour of some basic typeclasses
The cats toolbox a quick tour of some basic typeclasses
 
Real world gobbledygook
Real world gobbledygookReal world gobbledygook
Real world gobbledygook
 
Introduction to type classes in 30 min
Introduction to type classes in 30 minIntroduction to type classes in 30 min
Introduction to type classes in 30 min
 
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
 
Getting Started with PureScript
Getting Started with PureScriptGetting Started with PureScript
Getting Started with PureScript
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
 
Apache spark when things go wrong
Apache spark   when things go wrongApache spark   when things go wrong
Apache spark when things go wrong
 
Introduction to type classes
Introduction to type classesIntroduction to type classes
Introduction to type classes
 
FP is coming... le 19/05/2016
FP is coming... le 19/05/2016FP is coming... le 19/05/2016
FP is coming... le 19/05/2016
 
Writing your own RDD for fun and profit
Writing your own RDD for fun and profitWriting your own RDD for fun and profit
Writing your own RDD for fun and profit
 
Implementing pattern-matching in JavaScript (short version)
Implementing pattern-matching in JavaScript (short version)Implementing pattern-matching in JavaScript (short version)
Implementing pattern-matching in JavaScript (short version)
 
Functional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heavenFunctional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heaven
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and Future
 
Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!
 
Apache spark workshop
Apache spark workshopApache spark workshop
Apache spark workshop
 
Origins of free
Origins of freeOrigins of free
Origins of free
 
Dracula
DraculaDracula
Dracula
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free Monads
 

Similar to Going bananas with recursion schemes for expression evaluation

Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meetMario Fusco
 
Futzing with actors (etc.)
Futzing with actors (etc.)Futzing with actors (etc.)
Futzing with actors (etc.)league
 
3.7 Indexed families of sets
3.7 Indexed families of sets3.7 Indexed families of sets
3.7 Indexed families of setsJan Plaza
 
Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)intelliyole
 
Integration by Parts, Part 2
Integration by Parts, Part 2Integration by Parts, Part 2
Integration by Parts, Part 2Pablo Antuna
 
Definition ofvectorspace
Definition ofvectorspaceDefinition ofvectorspace
Definition ofvectorspaceTanuj Parikh
 
Dynamic Programming for 4th sem cse students
Dynamic Programming for 4th sem cse studentsDynamic Programming for 4th sem cse students
Dynamic Programming for 4th sem cse studentsDeepakGowda357858
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
Scala for ruby programmers
Scala for ruby programmersScala for ruby programmers
Scala for ruby programmerstymon Tobolski
 
Concurrent Application Development using Scala
Concurrent Application Development using ScalaConcurrent Application Development using Scala
Concurrent Application Development using ScalaSiarhiej Siemianchuk
 
ecoop-slides.pdf
ecoop-slides.pdfecoop-slides.pdf
ecoop-slides.pdfAndongFAN
 
Multilinear Twisted Paraproducts
Multilinear Twisted ParaproductsMultilinear Twisted Paraproducts
Multilinear Twisted ParaproductsVjekoslavKovac1
 
여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala LanguageAshal aka JOKER
 
Scope Graphs: A fresh look at name binding in programming languages
Scope Graphs: A fresh look at name binding in programming languagesScope Graphs: A fresh look at name binding in programming languages
Scope Graphs: A fresh look at name binding in programming languagesEelco Visser
 
Comparison market implied volatilities with implied volatilities computed by ...
Comparison market implied volatilities with implied volatilities computed by ...Comparison market implied volatilities with implied volatilities computed by ...
Comparison market implied volatilities with implied volatilities computed by ...Yuan Jing
 
ハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使うハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使うbpstudy
 

Similar to Going bananas with recursion schemes for expression evaluation (20)

Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
 
Futzing with actors (etc.)
Futzing with actors (etc.)Futzing with actors (etc.)
Futzing with actors (etc.)
 
3.7 Indexed families of sets
3.7 Indexed families of sets3.7 Indexed families of sets
3.7 Indexed families of sets
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)
 
Integration by Parts, Part 2
Integration by Parts, Part 2Integration by Parts, Part 2
Integration by Parts, Part 2
 
final19
final19final19
final19
 
Definition ofvectorspace
Definition ofvectorspaceDefinition ofvectorspace
Definition ofvectorspace
 
Dynamic Programming for 4th sem cse students
Dynamic Programming for 4th sem cse studentsDynamic Programming for 4th sem cse students
Dynamic Programming for 4th sem cse students
 
Lisp
LispLisp
Lisp
 
Monadologie
MonadologieMonadologie
Monadologie
 
Scala for ruby programmers
Scala for ruby programmersScala for ruby programmers
Scala for ruby programmers
 
Concurrent Application Development using Scala
Concurrent Application Development using ScalaConcurrent Application Development using Scala
Concurrent Application Development using Scala
 
ecoop-slides.pdf
ecoop-slides.pdfecoop-slides.pdf
ecoop-slides.pdf
 
Ch4
Ch4Ch4
Ch4
 
Multilinear Twisted Paraproducts
Multilinear Twisted ParaproductsMultilinear Twisted Paraproducts
Multilinear Twisted Paraproducts
 
여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language
 
Scope Graphs: A fresh look at name binding in programming languages
Scope Graphs: A fresh look at name binding in programming languagesScope Graphs: A fresh look at name binding in programming languages
Scope Graphs: A fresh look at name binding in programming languages
 
Comparison market implied volatilities with implied volatilities computed by ...
Comparison market implied volatilities with implied volatilities computed by ...Comparison market implied volatilities with implied volatilities computed by ...
Comparison market implied volatilities with implied volatilities computed by ...
 
ハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使うハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使う
 

More from Pawel Szulc

Getting acquainted with Lens
Getting acquainted with LensGetting acquainted with Lens
Getting acquainted with LensPawel Szulc
 
Maintainable Software Architecture in Haskell (with Polysemy)
Maintainable Software Architecture in Haskell (with Polysemy)Maintainable Software Architecture in Haskell (with Polysemy)
Maintainable Software Architecture in Haskell (with Polysemy)Pawel Szulc
 
Painless Haskell
Painless HaskellPainless Haskell
Painless HaskellPawel Szulc
 
Trip with monads
Trip with monadsTrip with monads
Trip with monadsPawel Szulc
 
Trip with monads
Trip with monadsTrip with monads
Trip with monadsPawel Szulc
 
Illogical engineers
Illogical engineersIllogical engineers
Illogical engineersPawel Szulc
 
RChain - Understanding Distributed Calculi
RChain - Understanding Distributed CalculiRChain - Understanding Distributed Calculi
RChain - Understanding Distributed CalculiPawel Szulc
 
Illogical engineers
Illogical engineersIllogical engineers
Illogical engineersPawel Szulc
 
Understanding distributed calculi in Haskell
Understanding distributed calculi in HaskellUnderstanding distributed calculi in Haskell
Understanding distributed calculi in HaskellPawel Szulc
 
Software engineering the genesis
Software engineering  the genesisSoftware engineering  the genesis
Software engineering the genesisPawel Szulc
 
Category theory is general abolute nonsens
Category theory is general abolute nonsensCategory theory is general abolute nonsens
Category theory is general abolute nonsensPawel Szulc
 
Fun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming languageFun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming languagePawel Szulc
 
Know your platform. 7 things every scala developer should know about jvm
Know your platform. 7 things every scala developer should know about jvmKnow your platform. 7 things every scala developer should know about jvm
Know your platform. 7 things every scala developer should know about jvmPawel Szulc
 
Monads asking the right question
Monads  asking the right questionMonads  asking the right question
Monads asking the right questionPawel Szulc
 
Apache Spark 101 [in 50 min]
Apache Spark 101 [in 50 min]Apache Spark 101 [in 50 min]
Apache Spark 101 [in 50 min]Pawel Szulc
 
Javascript development done right
Javascript development done rightJavascript development done right
Javascript development done rightPawel Szulc
 
Architektura to nie bzdura
Architektura to nie bzduraArchitektura to nie bzdura
Architektura to nie bzduraPawel Szulc
 
Testing and Testable Code
Testing and Testable CodeTesting and Testable Code
Testing and Testable CodePawel Szulc
 

More from Pawel Szulc (19)

Getting acquainted with Lens
Getting acquainted with LensGetting acquainted with Lens
Getting acquainted with Lens
 
Impossibility
ImpossibilityImpossibility
Impossibility
 
Maintainable Software Architecture in Haskell (with Polysemy)
Maintainable Software Architecture in Haskell (with Polysemy)Maintainable Software Architecture in Haskell (with Polysemy)
Maintainable Software Architecture in Haskell (with Polysemy)
 
Painless Haskell
Painless HaskellPainless Haskell
Painless Haskell
 
Trip with monads
Trip with monadsTrip with monads
Trip with monads
 
Trip with monads
Trip with monadsTrip with monads
Trip with monads
 
Illogical engineers
Illogical engineersIllogical engineers
Illogical engineers
 
RChain - Understanding Distributed Calculi
RChain - Understanding Distributed CalculiRChain - Understanding Distributed Calculi
RChain - Understanding Distributed Calculi
 
Illogical engineers
Illogical engineersIllogical engineers
Illogical engineers
 
Understanding distributed calculi in Haskell
Understanding distributed calculi in HaskellUnderstanding distributed calculi in Haskell
Understanding distributed calculi in Haskell
 
Software engineering the genesis
Software engineering  the genesisSoftware engineering  the genesis
Software engineering the genesis
 
Category theory is general abolute nonsens
Category theory is general abolute nonsensCategory theory is general abolute nonsens
Category theory is general abolute nonsens
 
Fun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming languageFun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming language
 
Know your platform. 7 things every scala developer should know about jvm
Know your platform. 7 things every scala developer should know about jvmKnow your platform. 7 things every scala developer should know about jvm
Know your platform. 7 things every scala developer should know about jvm
 
Monads asking the right question
Monads  asking the right questionMonads  asking the right question
Monads asking the right question
 
Apache Spark 101 [in 50 min]
Apache Spark 101 [in 50 min]Apache Spark 101 [in 50 min]
Apache Spark 101 [in 50 min]
 
Javascript development done right
Javascript development done rightJavascript development done right
Javascript development done right
 
Architektura to nie bzdura
Architektura to nie bzduraArchitektura to nie bzdura
Architektura to nie bzdura
 
Testing and Testable Code
Testing and Testable CodeTesting and Testable Code
Testing and Testable Code
 

Recently uploaded

GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 

Recently uploaded (20)

GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 

Going bananas with recursion schemes for expression evaluation

  • 1. “Going bananas with recursion schemes for fixed point data types”
  • 9. Can we actually can Build some Stuff?
  • 14. Recursive Structures are common ● ○ ■ ■ ○ ■ ■
  • 15. Recursive Structures are common ● ○ ■ ■ ○ ■ ■ ● ○ ○ ○
  • 16. Recursive Structures are common ● ○ ■ ■ ○ ■ ■ ● ○ ○ ○ ●
  • 27. data Exp = IntVal Int | DecVal Double | Sum Exp Exp | Multiply Exp Exp | Divide Exp Exp | Square Exp
  • 28. data Exp = IntVal Int | DecVal Double | Sum Exp Exp | Multiply Exp Exp | Divide Exp Exp | Square Exp sealed trait Exp final case class IntValue(v: Int) extends Exp final case class DecValue(v: Double) extends Exp final case class Sum(exp1: Exp, exp2: Exp) extends Exp final case class Multiply(exp1: Exp, exp2: Exp) extends Exp final case class Divide(exp1: Exp, exp2: Exp) extends Exp final case class Square(exp: Exp) extends Exp
  • 29. data Exp = IntVal Int | DecVal Double | Sum Exp Exp | Multiply Exp Exp | Divide Exp Exp | Square Exp sealed trait Exp final case class IntValue(v: Int) extends Exp final case class DecValue(v: Double) extends Exp final case class Sum(exp1: Exp, exp2: Exp) extends Exp final case class Multiply(exp1: Exp, exp2: Exp) extends Exp final case class Divide(exp1: Exp, exp2: Exp) extends Exp final case class Square(exp: Exp) extends Exp
  • 30. sealed trait Exp final case class IntValue(v: Int) extends Exp final case class DecValue(v: Double) extends Exp final case class Sum(exp1: Exp, exp2: Exp) extends Exp final case class Multiply(exp1: Exp, exp2: Exp) extends Exp final case class Divide(exp1: Exp, exp2: Exp) extends Exp final case class Square(exp: Exp) extends Exp val evaluate: Exp => Double =
  • 31. sealed trait Exp final case class IntValue(v: Int) extends Exp final case class DecValue(v: Double) extends Exp final case class Sum(exp1: Exp, exp2: Exp) extends Exp final case class Multiply(exp1: Exp, exp2: Exp) extends Exp final case class Divide(exp1: Exp, exp2: Exp) extends Exp final case class Square(exp: Exp) extends Exp val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) }
  • 32. sealed trait Exp final case class IntValue(v: Int) extends Exp final case class DecValue(v: Double) extends Exp final case class Sum(exp1: Exp, exp2: Exp) extends Exp final case class Multiply(exp1: Exp, exp2: Exp) extends Exp final case class Divide(exp1: Exp, exp2: Exp) extends Exp final case class Square(exp: Exp) extends Exp val mkString: Exp => String = { case IntValue(v) => v.toString case DecValue(v) => v.toString case Sum(exp1, exp2) => s"( ${mkStr(exp1)} + ${mkStr(exp2)})" case Multiply(exp1, exp2) => s"( ${mkStr(exp1)} * ${mkStr(exp2)})" case Square(exp) => s"(${mkStr(exp)})^2" case Divide(exp1, exp2) => s"( ${mkStr(exp1)} / ${mkStr(exp2)})" }
  • 33. sealed trait Exp final case class IntValue(v: Int) extends Exp final case class DecValue(v: Double) extends Exp final case class Sum(exp1: Exp, exp2: Exp) extends Exp final case class Multiply(exp1: Exp, exp2: Exp) extends Exp final case class Divide(exp1: Exp, exp2: Exp) extends Exp final case class Square(exp: Exp) extends Exp val optimize: Exp => Exp = { case Multiply(exp1, exp2) if(exp1 == exp2) => Square(optimize(exp1))
  • 34. sealed trait Exp final case class IntValue(v: Int) extends Exp final case class DecValue(v: Double) extends Exp final case class Sum(exp1: Exp, exp2: Exp) extends Exp final case class Multiply(exp1: Exp, exp2: Exp) extends Exp final case class Divide(exp1: Exp, exp2: Exp) extends Exp final case class Square(exp: Exp) extends Exp val optimize: Exp => Exp = { case Multiply(exp1, exp2) if(exp1 == exp2) => Square(optimize(exp1)) case IntValue(v) => IntValue(v) case DecValue(v) => DecValue(v) case Sum(exp1, exp2) => Sum(optimize(exp1), optimize(exp2)) case Multiply(exp1, exp2) => Multiply(optimize(exp1), optimize(exp2)) case Square(exp) => Square(optimize(exp)) case Divide(exp1, exp2) => Divide(optimize(exp1), optimize(exp2)) }
  • 35. sealed trait Exp final case class IntValue(v: Int) extends Exp final case class DecValue(v: Double) extends Exp final case class Sum(exp1: Exp, exp2: Exp) extends Exp final case class Multiply(exp1: Exp, exp2: Exp) extends Exp final case class Divide(exp1: Exp, exp2: Exp) extends Exp final case class Square(exp: Exp) extends Exp val optimize: Exp => Exp = { case Multiply(exp1, exp2) if(exp1 == exp2) => Square(optimize(exp1)) case IntValue(v) => IntValue(v) case DecValue(v) => DecValue(v) case Sum(exp1, exp2) => Sum(optimize(exp1), optimize(exp2)) case Multiply(exp1, exp2) => Multiply(exp1, optimize(exp2)) case Square(exp) => Square(optimize(exp)) case Divide(exp1, exp2) => Divide(optimize(exp1), optimize(exp2)) }
  • 36. sealed trait Exp final case class IntValue(v: Int) extends Exp final case class DecValue(v: Double) extends Exp final case class Sum(exp1: Exp, exp2: Exp) extends Exp final case class Multiply(exp1: Exp, exp2: Exp) extends Exp final case class Divide(exp1: Exp, exp2: Exp) extends Exp final case class Square(exp: Exp) extends Exp val optimize: Exp => Exp = { case Multiply(exp1, exp2) if(exp1 == exp2) => Square(optimize(exp1)) case IntValue(v) => optimize(IntValue(v)) case DecValue(v) => optimize(DecValue(v)) case Sum(exp1, exp2) => Sum(optimize(exp1), optimize(exp2)) case Multiply(exp1, exp2) => Multiply(optimize(exp1), optimize(exp2)) case Square(exp) => Square(optimize(exp)) case Divide(exp1, exp2) => Divide(optimize(exp1), optimize(exp2)) }
  • 37. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 38. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 39. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 40. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 41. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 42. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 43. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 44. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 45. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 46. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 47. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 48. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 49. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 50. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 51. val mkString: Exp => String = { case IntValue(v) => v.toString case DecValue(v) => v.toString case Sum(exp1, exp2) => s"(${mkStr(exp1)} + ${mkStr(exp2)})" case Multiply(exp1, exp2) => s"(${mkStr(exp1)} * ${mkStr(exp2)})" case Square(exp) => s"(${mkStr(exp)})^2" case Divide(exp1, exp2) => s"( ${mkStr(exp1)} / ${mkStr(exp2)})" } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 52. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 53. sealed trait Exp final case class IntValue(v: Int) extends Exp final case class DecValue(v: Double) extends Exp final case class Sum(exp1: Exp, exp2: Exp) extends Exp final case class Multiply(exp1: Exp, exp2: Exp) extends Exp final case class Divide(exp1: Exp, exp2: Exp) extends Exp final case class Square(exp: Exp) extends Exp
  • 54. sealed trait Exp final case class IntValue(v: Int) extends Exp final case class DecValue(v: Double) extends Exp final case class Sum(exp1: Exp, exp2: Exp) extends Exp final case class Multiply(exp1: Exp, exp2: Exp) extends Exp final case class Divide(exp1: Exp, exp2: Exp) extends Exp final case class Square(exp: Exp) extends Exp sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A]
  • 55. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp1: Exp[?] = Sum[?](IntValue[?](10), IntValue[?](5)) )
  • 56. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp1: Exp[?] = Sum[?](IntValue[Unit](10), IntValue[Unit](5)) )
  • 57. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp1: Exp[?] = Sum[?](IntValue[Unit](10), IntValue[Unit](5)) ) Exp[Unit]
  • 58. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp1: Exp[?] = Sum[?](IntValue[Unit](10), IntValue[Unit](5)) ) Exp[Unit]
  • 59. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp1: Exp[?] = Sum[?](IntValue[Unit](10), IntValue[Unit](5)) )
  • 60. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp1: Exp[?] = Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) )
  • 61. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) )
  • 62. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp2: Exp = Divide( DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) val exp2: Exp[?] = Divide[?]( DecValue[?](5.2), Sum[?](IntValue[?](10), IntValue[?](5)) ) )
  • 63. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp2: Exp = Divide( DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) val exp2: Exp[?] = Divide[?]( DecValue[?](5.2), Sum[?](IntValue[Unit](10), IntValue[Unit](5)) ) )
  • 64. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp2: Exp = Divide( DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) val exp2: Exp[?] = Divide[?]( DecValue[?](5.2), Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) )
  • 65. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp2: Exp = Divide( DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) val exp2: Exp[?] = Divide[?]( DecValue[Exp[Unit]](5.2), Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) )
  • 66. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp2: Exp = Divide( DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) val exp2: Exp[?] = Divide[Exp[Exp[Unit]]]( DecValue[Exp[Unit]](5.2), Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) )
  • 67. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp2: Exp = Divide( DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) val exp2: Exp[Exp[Exp[Unit]]] = Divide[Exp[Exp[Unit]]]( DecValue[Exp[Unit]](5.2), Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) )
  • 68. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp2: Exp = Divide( DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) val exp2: Exp[Exp[Exp[Unit]]] = Divide[Exp[Exp[Unit]]]( DecValue[Exp[Unit]](5.2), Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) )
  • 69. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp2: Exp = Divide( DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) val exp2: Exp[Exp[Exp[Unit]]] = Divide[Exp[Exp[Unit]]]( DecValue[Exp[Unit]](5.2), Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) )
  • 70. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp2: Exp = Divide( DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) val exp3: Exp = from(input) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) val exp2: Exp[Exp[Exp[Unit]]] = Divide[Exp[Exp[Unit]]]( DecValue[Exp[Unit]](5.2), Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) ) val exp3: Exp[?] = from(input)
  • 71. sealed trait Exp[A] final case class IntValue[A](v: Int) extends Exp[A] final case class DecValue[A](v: Double) extends Exp[A] final case class Sum[A](exp1: A, exp2: A) extends Exp[A] final case class Multiply[A](exp1: A, exp2: A) extends Exp[A] final case class Divide[A](exp1: A, exp2: A) extends Exp[A] final case class Square[A](exp: A) extends Exp[A] val exp1: Exp = Sum(IntValue(10), IntValue(5)) ) val exp2: Exp = Divide( DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) val exp3: Exp = from(input) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) val exp2: Exp[Exp[Exp[Unit]]] = Divide[Exp[Exp[Unit]]]( DecValue[Exp[Unit]](5.2), Sum[Exp[Unit]](IntValue[Unit](10), IntValue[Unit](5)) ) ) val exp3: Exp[Exp[Exp[Exp[Exp[Exp[Exp[Exp[Exp[Ex
  • 73. Fix
  • 74.
  • 76. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]]( IntValue[Unit](10), IntValue[Unit](5) )
  • 77. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]]( Fix(IntValue[Unit](10)), Fix(IntValue[Unit](5)) )
  • 78. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Exp[Exp[Unit]] = Sum[Exp[Unit]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5)) )
  • 79. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Exp[Exp[Unit]] = Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5)) )
  • 80. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Exp[Exp[Unit]] = Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5)) ))
  • 81. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Fix[Exp] = Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5)) ))
  • 82. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Fix[Exp] = Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5)) )) val exp2: Exp[Exp[Exp[Unit]]] = Divide[Exp[Exp[Unit]]]( DecValue[Exp[Unit]](5.2), Sum[Exp[Unit]]( IntValue[Unit](10), IntValue[Unit](5)) ) )
  • 83. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Fix[Exp] = Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5)) )) val exp2: Exp[Exp[Exp[Unit]]] = Divide[Exp[Exp[Unit]]]( DecValue[Exp[Unit]](5.2), Sum[Exp[Unit]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5))) ) )
  • 84. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Fix[Exp] = Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5)) )) val exp2: Exp[Exp[Exp[Unit]]] = Divide[Exp[Exp[Unit]]]( DecValue[Exp[Unit]](5.2), Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5))) ) )
  • 85. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Fix[Exp] = Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5)) )) val exp2: Exp[Exp[Exp[Unit]]] = Divide[Exp[Exp[Unit]]]( Fix(DecValue[Fix[Exp]](5.2)), Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5))) ) )
  • 86. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Fix[Exp] = Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5)) )) val exp2: Exp[Exp[Exp[Unit]]] = Divide[Exp[Exp[Unit]]]( Fix(DecValue[Fix[Exp]](5.2)), Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5))) )) )
  • 87. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Fix[Exp] = Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5)) )) val exp2: Exp[Exp[Exp[Unit]]] = Fix(Divide[Fix[Exp]]( Fix(DecValue[Fix[Exp]](5.2)), Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5))) )) ))
  • 88. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Fix[Exp] = Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5)) )) val exp2: Fix[Exp] = Fix(Divide[Fix[Exp]]( Fix(DecValue[Fix[Exp]](5.2)), Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5))) )) ))
  • 89. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Fix[Exp] = Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5)) )) val exp2: Fix[Exp] = Fix(Divide[Fix[Exp]]( Fix(DecValue[Fix[Exp]](5.2)), Fix(Sum[Fix[Exp]]( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](5))) )) ))
  • 90. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Fix[Exp] = Fix(Sum( Fix(IntValue(10)), Fix(IntValue(5)) )) val exp2: Fix[Exp] = Fix(Divide( Fix(DecValue(5.2)), Fix(Sum( Fix(IntValue(10)), Fix(IntValue(5)) )) ))
  • 91. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Fix[Exp] = Fix(Sum( Fix(IntValue(10)), Fix(IntValue(5)) )) val exp2: Fix[Exp] = Fix(Divide( Fix(DecValue(5.2)), Fix(Sum( Fix(IntValue(10)), Fix(IntValue(5)) )) ))
  • 92. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Fix[Exp] = Fix(Sum( Fix(IntValue(10)), Fix(IntValue(5)) )) val exp2: Fix[Exp] = Fix(Divide( Fix(DecValue(5.2)), Fix(Sum( Fix(IntValue(10)), Fix(IntValue(5)) )) ))
  • 93. case class Fix[F[_]](unFix: F[Fix[F]]) val exp1: Fix[Exp] = Fix(Sum( Fix(IntValue(10)), Fix(IntValue(5)) )) val exp2: Fix[Exp] = Fix(Divide( Fix(DecValue(5.2)), Fix(Sum( Fix(IntValue(10)), Fix(IntValue(5)) )) )) val exp3: Fix[Exp] = from(input)
  • 94. val evaluate: Exp => Double = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(exp1, exp2) => evaluate(exp1) + evaluate(exp2) case Multiply(exp1, exp2) => evaluate(exp1) * evaluate(exp2) case Square(exp) => val v = evaluate(exp) v * v case Divide(exp1, exp2) => evaluate(exp1) / evaluate(exp2) } val exp = Multiply( Sum(IntValue(10), DecValue(2.5)), Divide(DecValue(5.2), Sum(IntValue(10), IntValue(5)) ) ) Multiply Sum Divide Int(10) Dec(2.5) Dec(5.2) Sum Int(10) Int(5)
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 113. Functor 101 trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] }
  • 114. Functor 101 trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] } def foo[A[_], T](a: A[T])
  • 115. Functor 101 trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] } def foo[A[_], T](a: A[T])(trans: T => Int)
  • 116. Functor 101 trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] } def foo[A[_], T](a: A[T])(trans: T => Int): A[Int] = ???
  • 117. Functor 101 trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] } def foo[A[_] : Functor, T](a: A[T])(trans: T => Int): A[Int] = ???
  • 118. Functor 101 trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] } def foo[A[_] : Functor, T](a: A[T])(trans: T => Int): A[Int] = a.map(trans)
  • 119. Functor 101 trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] } def foo[A[_] : Functor, T](a: A[T])(trans: T => Int): A[Int] = a.map(trans) case class Container[T](t: T) val r: Container[Int] = foo[Container, String](Container("bar"))(str => str.length)
  • 120. Functor 101 trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] } def foo[A[_] : Functor, T](a: A[T])(trans: T => Int): A[Int] = a.map(trans) implicit val functor: Functor[Container] = new Functor[Container] { def map[A, B](c: Container[A])(f: A => B): Container[B] = Container(f(c.t)) } case class Container[T](t: T) val r: Container[Int] = foo[Container, String](Container("bar"))(str => str.length)
  • 121. sealed trait Exp final case class IntValue(v: Int) extends Exp final case class DecValue(v: Double) extends Exp final case class Sum(exp1: Exp, exp2: Exp) extends Exp final case class Multiply(exp1: Exp, exp2: Exp) extends Exp final case class Divide(exp1: Exp, exp2: Exp) extends Exp final case class Square(exp: Exp) extends Exp implicit val functor: Functor[Exp] = new Functor[Exp] { def map[A, B](exp: Exp[A])(f: A => B): Exp[B] =
  • 122. sealed trait Exp final case class IntValue(v: Int) extends Exp final case class DecValue(v: Double) extends Exp final case class Sum(exp1: Exp, exp2: Exp) extends Exp final case class Multiply(exp1: Exp, exp2: Exp) extends Exp final case class Divide(exp1: Exp, exp2: Exp) extends Exp final case class Square(exp: Exp) extends Exp implicit val functor: Functor[Exp] = new Functor[Exp] { def map[A, B](exp: Exp[A])(f: A => B): Exp[B] = exp match { case Sum(a1, a2) => Sum(f(a1), f(a2)) case Multiply(a1, a2) => Multiply(f(a1), f(a2)) case Divide(a1, a2) => Divide(f(a1), f(a2)) case Square(a) => Square(f(a)) case IntValue(v) => IntValue(v) case DecValue(v) => DecValue(v) } }
  • 127. type Algebra[F[_], A] = F[A] => A val evaluate: Algebra[Exp, Double] = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(a1, a2) => a1 + a2 case Multiply(a1, a2) => a1 * a2 case Square(a) => a * a case Divide(a1, a2) => a1 / a2 }
  • 128. type Algebra[F[_], A] = F[A] => A val evaluate: Algebra[Exp, Double] = { case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(a1, a2) => a1 + a2 case Multiply(a1, a2) => a1 * a2 case Square(a) => a * a case Divide(a1, a2) => a1 / a2 } val mkStr: Algebra[Exp, String] = { case IntValue(v) => v.toString case DecValue(v) => v.toString case Sum(a1, a2) => s"($a1 + $a2)" case Multiply(a1, a2) => s"($a1 + $a2)" case Square(a) => s"($a)^2" case Divide(a1, a2) => s"($a1 + $a2)" }
  • 129. val evaluate: Algebra[Exp, Double] = { // Exp[Double] => Double case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(a1, a2) => a1 + a2 case Multiply(a1, a2) => a1 * a2 case Square(a) => a * a case Divide(a1, a2) => a1 / a2 }
  • 130. val evaluate: Algebra[Exp, Double] = { // Exp[Double] => Double case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(a1, a2) => a1 + a2 case Multiply(a1, a2) => a1 * a2 case Square(a) => a * a case Divide(a1, a2) => a1 / a2 } val exp2: Fix[Exp] = Fix(Divide( Fix(DecValue(5.2)), Fix(Sum( Fix(IntValue(10)), Fix(IntValue(5)) )) ))
  • 131. val evaluate: Algebra[Exp, Double] = { // Exp[Double] => Double case IntValue(v) => v.toDouble case DecValue(v) => v case Sum(a1, a2) => a1 + a2 case Multiply(a1, a2) => a1 * a2 case Square(a) => a * a case Divide(a1, a2) => a1 / a2 } val exp2: Fix[Exp] = Fix(Divide( Fix(DecValue(5.2)), Fix(Sum( Fix(IntValue(10)), Fix(IntValue(5)) )) )) > exp2.cata(evaluate) 0.3466666666666667
  • 132. val mkStr: Algebra[Exp, String] = { // Exp[Double] => Double case IntValue(v) => v.toString case DecValue(v) => v.toString case Sum(a1, a2) => s"($a1 + $a2)" case Multiply(a1, a2) => s"($a1 + $a2)" case Square(a) => s"($a)^2" case Divide(a1, a2) => s"($a1 + $a2)" }
  • 133. val mkStr: Algebra[Exp, String] = { // Exp[Double] => Double case IntValue(v) => v.toString case DecValue(v) => v.toString case Sum(a1, a2) => s"($a1 + $a2)" case Multiply(a1, a2) => s"($a1 + $a2)" case Square(a) => s"($a)^2" case Divide(a1, a2) => s"($a1 + $a2)" } val exp2: Fix[Exp] = Fix(Divide( Fix(DecValue(5.2)), Fix(Sum( Fix(IntValue(10)), Fix(IntValue(5)) )) ))
  • 134. val mkStr: Algebra[Exp, String] = { // Exp[Double] => Double case IntValue(v) => v.toString case DecValue(v) => v.toString case Sum(a1, a2) => s"($a1 + $a2)" case Multiply(a1, a2) => s"($a1 + $a2)" case Square(a) => s"($a)^2" case Divide(a1, a2) => s"($a1 + $a2)" } val exp2: Fix[Exp] = Fix(Divide( Fix(DecValue(5.2)), Fix(Sum( Fix(IntValue(10)), Fix(IntValue(5)) )) )) > exp2.cata(mkStr) (5.2 + (10 + 5))
  • 135. val optimize: Exp => Exp = { case Multiply(exp1, exp2) if(exp1 == exp2) => Square(optimize(exp1)) case IntValue(v) => IntValue(v) case DecValue(v) => DecValue(v) case Sum(exp1, exp2) => Sum(optimize(exp1), optimize(exp2)) case Multiply(exp1, exp2) => Multiply(optimize(exp1), optimize(exp2)) case Square(exp) => Square(optimize(exp)) case Divide(exp1, exp2) => Divide(optimize(exp1), optimize(exp2)) }
  • 136. val optimize: Exp => Exp = { case Multiply(exp1, exp2) if(exp1 == exp2) => Square(optimize(exp1)) case IntValue(v) => IntValue(v) case DecValue(v) => DecValue(v) case Sum(exp1, exp2) => Sum(optimize(exp1), optimize(exp2)) case Multiply(exp1, exp2) => Multiply(optimize(exp1), optimize(exp2)) case Square(exp) => Square(optimize(exp)) case Divide(exp1, exp2) => Divide(optimize(exp1), optimize(exp2)) } val optimize: Algebra[Exp, Fix[Exp]] = { // Exp[Fix[Exp]] => Fix[Exp] case Multiply(Fix(a1), Fix(a2)) if(a1 == a2) => Fix(Square(Fix(a1))) case other => Fix(other) }
  • 137. val optimize: Algebra[Exp, Fix[Exp]] = { // Exp[Fix[Exp]] => Fix[Exp] case Multiply(Fix(a1), Fix(a2)) if(a1 == a2) => Fix(Square(Fix(a1))) case other => Fix(other) }
  • 138. val optimize: Algebra[Exp, Fix[Exp]] = { // Exp[Fix[Exp]] => Fix[Exp] case Multiply(Fix(a1), Fix(a2)) if(a1 == a2) => Fix(Square(Fix(a1))) case other => Fix(other) } val aTimesAExp: Fix[Exp] = Fix(Multiply( Fix(Sum( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](20)) )), Fix(Sum( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](20)) )) ))
  • 139. val optimize: Algebra[Exp, Fix[Exp]] = { // Exp[Fix[Exp]] => Fix[Exp] case Multiply(Fix(a1), Fix(a2)) if(a1 == a2) => Fix(Square(Fix(a1))) case other => Fix(other) } val aTimesAExp: Fix[Exp] = Fix(Multiply( Fix(Sum( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](20)) )), Fix(Sum( Fix(IntValue[Fix[Exp]](10)), Fix(IntValue[Fix[Exp]](20)) )) )) > aTimesAExp.cata(optimize) Fix(Square(Fix(Sum(Fix(IntValue(10)),Fix(IntValue(20))))))
  • 145. type Coalgebra[F[_], A] = A => F[A]
  • 146. type Coalgebra[F[_], A] = A => F[A] val divisors: Coalgebra[Exp, Int] = { case n if(n % 2 == 0 && n != 2) => Multiply(2, n / 2) case n => IntValue(n) }
  • 147. type Coalgebra[F[_], A] = A => F[A] val divisors: Coalgebra[Exp, Int] = { case n if(n % 2 == 0 && n != 2) => Multiply(2, n / 2) case n => IntValue(n) } > 12.ana[Fix, Exp](divisors)
  • 148. type Coalgebra[F[_], A] = A => F[A] val divisors: Coalgebra[Exp, Int] = { case n if(n % 2 == 0 && n != 2) => Multiply(2, n / 2) case n => IntValue(n) } > 12.ana[Fix, Exp](divisors) Fix(Multiply(Fix(IntValue(2)),Fix(Multiply(Fix(IntValue(2)),Fix(Multiply(Fix(IntVal ue(2)),Fix(IntValue(7))))))))
  • 155. val divisors: Coalgebra[Exp, Int] = { … } // Double => Exp[Double] val evaluate: Algebra[Exp, Double] = { … } // Exp[Double] => Double
  • 156. val divisors: Coalgebra[Exp, Int] = { … } // Double => Exp[Double] val evaluate: Algebra[Exp, Double] = { … } // Exp[Double] => Double describe("divisors") { it("once evaluated will give initial value") { forAll(positiveInt) { n => n.ana(divisiors).cata(evaluate) shouldEqual(n) } }
  • 157. val divisors: Coalgebra[Exp, Int] = { … } // Double => Exp[Double] val evaluate: Algebra[Exp, Double] = { … } // Exp[Double] => Double describe("divisors") { it("once evaluated will give initial value") { forAll(positiveInt) { n => n.hylo(evaluate, divisors) shouldEqual(n) } }
  • 159. To sum it up
  • 160. To sum it up ●
  • 161. To sum it up ● ●
  • 162. To sum it up ● ● ● ○ ○
  • 163. To sum it up ● ● ● ○ ○ ●
  • 164. To sum it up ● ● ● ○ ○ ● ●
  • 165. To sum it up ● ● ● ○ ○ ● ● ●