λλλλλ
data made λ
λλ λλ
λ
λ λ
out of λ
λ
λ λ
λ
λ
functions λ
λ
λ λ λ
λλλλ λ
λ λ
λλ λλ
λλλλλ
#ylj2016
@KenScambler For faster
monads!
Diogenes of Sinope
412 – 323 BC
• Simplest man of all time
• Obnoxious hobo
• Lived in a barrel
Diogenes of Sinope
412 – 323 BC
I’ve been using this bowl
like a sucker!
Um….
what
[a, b, c, d]
"abcd"
IF x THEN y ELSE z
INT
WHILE cond {…}
λa -> b STRUCT {
BOOL fields…
}
Strings are
[a, b, c, d]
pretty much
arrays
IF x THEN y ELSE z
INT
WHILE cond {…}
λa -> b STRUCT {
BOOL fields…
}
Recursion can [a, b, c, d]
do loops
IF x THEN y ELSE z
INT
λa -> b STRUCT {
BOOL fields…
}
Recursive data
structures can do
lists IF x THEN y ELSE z
INT
[a,b,c,d]
λa -> b STRUCT {
BOOL fields…
}
Ints can do bools
IF x THEN y ELSE z
INT
[a,b,c,d]
λa -> b STRUCT {
fields…
}
IF x THEN y ELSE z
INT
[a,b,c,d]
λa -> b STRUCT {
fields…
}
λa -> b
[a,b,c,d]
STRUCT
λa -> b
Lambda calculus
Alonzo Church
1903 - 1995
λa -> b
Lambda calculus
Alonzo Church
1903 - 1995
Church encoding
We can make any
data structure out of
functions!
Booleans
Bool
Church booleans
Bool result
Church booleans
If we define everything you
can do with a structure, isn’t
that the same as defining
Bool result
the structure itself?
TRUE
or
FALSE
“What we do if
it’s true”
TRUE result
or
FALSE
“What we do if
it’s false”
TRUE
or
FALSE result
TRUE result
or result
FALSE result
() result
result
() result
result
result
result
The Church encoding
of a boolean is:
r r r
type CBool = forall r. r -> r -> r
cTrue :: CBool
cTrue x y = x
cFalse :: CBool
cFalse x y = y
cNot :: CBool -> CBool
cNot cb = cb cFalse cTrue
cAnd :: CBool -> CBool -> CBool
cAnd cb1 cb2 = cb1 cb2 cFalse
cOr :: CBool -> CBool -> CBool
cOr cb1 cb2 = cb1 cTrue cb2
Natural numbers
0
1
2
3
4
…
Natural numbers
0
0 +1
0 +1 +1
0 +1 +1 +1
0 +1 +1 +1 +1
…
Natural numbers
0 Natural
0 +1 numbers form
0 +1 +1 a data
structure!
0 +1 +1 +1
0 +1 +1 +1 +1
…
Giuseppe Peano
1858 - 1932
Natural Peano numbers
Nat = Succ(Nat)
or
Zero
Giuseppe Peano
1858 - 1932
Now lets turn it
into functions!
Nat = Succ(Nat)
or
Zero
“If it’s a successor”
Succ(Nat) result
or
Zero
Succ(Nat)
or “If it’s zero”
Zero result
Succ(Nat) result
or result
Zero result
Nat result
result
() result
Nat result
result
result
Nat result
() result
Nat
() result
Nat
()
Nat
()
Nat
result result
result
result
The Church encoding
of natural numbers is:
(r r) r r
type CNat = forall r. (r -> r) -> r -> r
c0, c1, c2, c3, c4 :: CNat
c0 f z = z
c1 f z = f z
c2 f z = f (f z)
c3 f z = f (f (f z))
c4 f z = f (f (f (f z)))
cSucc :: CNat -> CNat
cSucc cn f = f . cn f
cPlus :: CNat -> CNat -> CNat
cPlus cn1 cn2 f = cn1 f . cn2 f
cMult :: CNat -> CNat -> CNat
cMult cn1 cn2 = cn1 . cn2
type CNat = forall r. (r -> r) -> r -> r
c0, c1, c2, c3, c4 :: CNat
c0 f = id
c1 f = f
c2 f = f . f
c3 f = f . f . f
c4 f = f . f . f . f
cSucc :: CNat -> CNat
cSucc cn f = f . cn f
cPlus :: CNat -> CNat -> CNat
cPlus cn1 cn2 f = cn1 f . cn2 f
cMult :: CNat -> CNat -> CNat
cMult cn1 cn2 = cn1 . cn2
Performance
Native ints Peano numbers Church numbers
addition O(n) O(1)
O(n2) O(1)
multiplication
O(n) O(n)
print
Performance
Native ints Peano numbers Church numbers
addition O(n) O(1)
O(n2) O(1)
multiplication
O(n) O(n)
print
Church encoding cheat sheet
A a r
A|B (a r) (b r) r
(A, B) (a b r) r
Singleton r
Recursion r r
Cons lists
List a = Cons(a, List a)
or
Nil
Cons(a, List a) result
or result
Nil result
(a, List a) result
result
() result
(a, result) result
result
result
a result result
result
result
The Church encoding
of lists is:
(a r r) r r
The Church encoding
of lists is:
(a r r) r r
AKA: foldr
Functors
a
Functors
a
f a
Functors
a
f a
f (f a)
They compose!
Functors
a
f a What if we make a
f (f a) “Church numeral” out of
f (f (f a)) them?
Free monads
a
f a
f (f a)
f (f (f a))
f (f (f (f a)))
Free monad >>=
a
Free monad >>=
a
fmap
Free monad >>=
f a
Free monad >>=
f a
fmap
Free monad >>=
f a
fmap
Free monad >>=
f (f a)
Free monad >>=
f (f a)
fmap
Free monad >>=
f (f a)
fmap
Free monad >>=
f (f a)
fmap
Free monad >>=
f (f (f a))
Free monad >>=
f (f (f a))
fmap
Free monad >>=
f (f (f a))
fmap
Free monad >>=
f (f (f a))
fmap
Free monad >>=
f (f (f a))
fmap
λn [n+1, n*2]
3
λn [n+1, n*2]
4 6
λn [n+1, n*2]
4 6 fmap
λn [n+1, n*2]
5 8 7 12
λn [n+1, n*2]
fmap
5 8 7 12
λn [n+1, n*2]
5 8 7 12 fmap
λn [n+1, n*2]
6 10 9 16 8 14 13 24
λn Wrap [Pure (n+1), Pure (n*2)]
3
λn Wrap [Pure (n+1), Pure (n*2)]
3 >>=
λn Wrap [Pure (n+1), Pure (n*2)]
4 6
λn Wrap [Pure (n+1), Pure (n*2)]
4 6 >>=
λn Wrap [Pure (n+1), Pure (n*2)]
4 6 fmap
λn Wrap [Pure (n+1), Pure (n*2)]
4 6 >>=
λn Wrap [Pure (n+1), Pure (n*2)]
5 8 7 12
λn Wrap [Pure (n+1), Pure (n*2)]
>>=
5 8 7 12
λn Wrap [Pure (n+1), Pure (n*2)]
fmap
5 8 7 12
λn Wrap [Pure (n+1), Pure (n*2)]
5 8 7 12 >>=
λn Wrap [Pure (n+1), Pure (n*2)]
5 8 7 12 fmap
λn Wrap [Pure (n+1), Pure (n*2)]
5 8 7 12 >>=
λn Wrap [Pure (n+1), Pure (n*2)]
6 10 9 16 8 14 13 24
Free monads
Free a = Wrap f (Free f a)
or
Pure a
Wrap f (Free f a) result
or result
Pure a result
f (Free f a) result
result
a result
f result result
result
a result
The Church encoding
of free monads is:
(f r r) (a r) r
Bind is constant time!
(f r r) (a r) r
>>=
CFree f b
λa -> b
λa -> b
∴
λa -> b
∴