В занимательной книженции Душкина «14 занимательных эссе о языке Haskell и функциональном программировании» в разделе про комбинаторы есть такой пример кода:
data Combinator = Var String
| App Combinator Combinator
| Lam String Combinator
deriving Eq
instance Show Combinator where
show (Var x)= x
show (App x y) = case y of
App _ _ -> showLam x ++
"(" ++
show y ++
")"
_ -> showLam x ++
showLam y
where
showLam l@(Lam _ _) = "(" ++
show l ++
")"
showLam x = show x
show (Lam x e) = "\\" ++
x ++
"."
++ show e
i = Var "I"
k = Var "K"
s = Var "S"
free :: String -> Combinator -> Bool
free x (Var y) = x == y
free x (App e1 e2) = free x e1 || free x e2
free x (Lam y e) = free x e
transform :: Combinator -> Combinator
transform (Var x) = Var x
transform (App x y) = App (transform x)
(transform y)
transform (Lam x (Var y)) | x == y
= i transform (Lam x e)
| (not . free x) e
= App k (transform e) transform (Lam x l@(Lam y e))
| free x e
= transform (Lam x (transform l))
transform (Lam x (App e1 e2))
= App (App s (transform (Lam x e1)))
(transform (Lam x e2))
transform (Lam x (Var y)) | x == y
= i transform (Lam x e)
| (not . free x) e
= App k (transform e) transform (Lam x l@(Lam y e))
transform :: Combinator -> Combinator
transform (Var x) = Var x
transform (App x y)= App (transform x)
(transform y)
transform e@(Lam x (Var y)) | x == y
= App i (transform (Lam x e))
| (not . free x) e
= App k (transform e)
transform (Lam x l@(Lam y e)) | free x e
= transform (Lam x (transform l))
transform (Lam x (App e1 e2))
= App (App s (transform (Lam x e1)))
(transform (Lam x e2))
Перемещено mono из talks