当然。我们可以根据lambda术语的定义直接生成它们。
在Haskell中,我们首先定义数据类型,
data LC a = Var a -- Constructor <type> <type> ...
| App (LC a) (LC a) --
| Lam a (LC a) -- ... alternatives ...
instance Show a => Show (LC a) -- `LC a` is in Show if `a` is in Show, and
where
show (Var i) = [c | c <- show i, c /= '\'']
show (App m n) = "(" ++ show m ++ " " ++ show n ++ ")"
show (Lam v b) = "(^" ++ show (Var v) ++ "." ++ show b ++ ")"
然后使用Fair(er)join
,
lambda :: [a] -> [LC a]
lambda vars = terms
where
terms = fjoin [ map Var vars ,
fjoin [ [App t s | t <- terms] | s <- terms ] ,
fjoin [ [Lam v s | v <- vars ] | s <- terms ] ]
fjoin :: [[a]] -> [a]
fjoin xs = go [] xs -- fairer join
where
go [] [] = []
go a b = reverse (concatMap (take 1) a) ++ go
(take 1 b ++ [t | (_:t) <- a]) (drop 1 b)
我们只列举它们,例如
> take 20 $ lambda "xyz"
[x,y,(x x),z,(y x),(^x.x),(x y),(^y.x),((x x) x),(^x.y),(y y),(^z.x),(x (x x)),
(^y.y),(z x),(^x.(x x)),((x x) y),(^z.y),(y (x x)),(^y.(x x))]
> take 5 $ drop 960 $ lambda "xyz"
[(((x x) y) (z x)),(^y.(^x.((x x) (x x)))),((^x.(x x)) (^x.(x x))),(^x.((^z.x)
y)),((z x) ((x x) y))]
看,著名的术语离顶部不远!Ω=(λx.xx)(λx.xx)
fjoin
相当于欧米茄monad的diagonal
。