承知しました。ラムダ項の定義に従って直接生成できます。
Haskellでは、最初に型を定義し、
data LC a = Var a | App (LC a) (LC a) | Lam a (LC a)
instance Show a => Show (LC a) 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 ++ ")"
そして次に
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 (take 1 xs) (drop 1 xs) -- fair 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
等価であるオメガモナドさんdiagonal
。