Some Notes And Some Code
FP
Lists are Monads too
instance Monad [] where
la >== a2lb = [ b | a <- la, b <- a2lb a]
return a = [a]
Digestive Functors
Jasper van der jeugd is a Belgian student who has been very active developing various libraries.
His blogs contain interesting libraries and examples, e.g. for
digenstive functors, which provide yet another example of the Applicative interface.
Lambda calculus
Booleans
true = \ t f -> t
false = \ t f -> f
if c t e = c t e
Pairs
pair = \ x y f -> f x y
fst = \ p -> p (\ x y -> x)
snd = \ p -> p (\ x y -> y)
Maybe
nothing = \ n j -> n
just = \ a -> \ n j -> j a
case v of
Nothing -> <expr1>
Just a -> <expr2>
becomes
v (<expr1>) (\ a -> <expr2>)
Natural numbers
data Nat = Zero
| Succ Nat
zero = \ z s -> z
succ = \ n -> \ z s -> s n
Lists
data List a = Nil
| Cons a (List a)
nil = \ n c -> n
cons = \ a la -> \ n c -> c a la
case v of
Nil -> <expr1>
Cons a la -> <expr2>
becomes
v (<expr1>) (\ a la -> <expr2>)
Non-recursive lets
let x = <e1> in <e2>
becomes
(\x . e2) e1
Recursion
Recusion is removed using the =fix=combinator, which itself can be written as a lambda-expression.
fix = \ f -> (\x -> f(x x)) )(\x -> f (x x)
fix f = (\x -> f(x x)) )(\x -> f (x x) = f ((\x -> f(x x)) )(\x -> f (x x)) = f (fix f)
Replacing all lambda expressions by S, K and I
S = \ f g x -> (f x) (g x)
K = \ y x -> y
I = \ x -> x
Even these can be replaced by using only a single combinator:
http://www.staff.science.uu.nl/~fokke101/article/combinat/index.html
X = \f.f S (\xyz.x)
K = X X
S = X K
Rewriting gives:
K y x
(\f.fS(\xyz.x)) X y x
X S (\xyz.x) y x
S S (\xyz.x) (\xyz.x) y x
S (\xyz.x) ((\xyz.x) (\xyz.x)) y x
(\ a b . y) ((\xyz.x) (\xyz.x)) x
y
X K f g x
K S (\xyx.x) f g x
S f g x
Lazy evaluation
Repmin
data Tree a = Leaf a
| Node (Tree a) (Tree a)
repmin t = let repmin' (Leaf v) m = (v, Leaf m)
repmin' (Node l r) m = let (ml, rl) = repmin' l m
(mr, rr) = repmin' r m
in (lm `min` rm, Bin rl rr)
(m,r) = repmin' t m -- !! we feed part of the result to the function call!
in r
Breadth-first labeling
data Tree a = Leaf
| Node (Tree a) a (Tree a)
deriving Show
-- the function bfl replaces the a's in a tree by consecutive values from the list [b] in a breadth-first way
bfl :: Tree a -> [b] -> Tree b
bfl t l = let bf Leaf lss = (Leaf, lss)
bf (Node lt _ rt) ((l:ls):lls) =
let (lr, ills) = bf lt lls
(rr, rlls) = bf rt ills
in (Node lr l rr, ls:rlls)
(result, nlevels) = bf t (l:nlevels)
in result
t :: Tree Int
t = Node (Node (Node Leaf 1 Leaf) 1 (Node Leaf 1 (Node Leaf 1 (Node Leaf 1 Leaf)))) 1 Leaf
{-
*Main> bfl t [1..]
Node (Node (Node Leaf 3 Leaf) 2 (Node Leaf 4 (Node Leaf 5 (Node Leaf 6 Leaf)))) 1 Leaf
-}
--
DoaitseSwierstra - 31 Oct 2011