-- See M. Douglas McIlroy, "Enumerating the strings of regular languages". undefined = undefined; data Bool = True | False; (==) x y = case x <= y of { True -> y <= x ; False -> x <= y }; ife b t f = case b of { True -> t ; False -> f }; foldr c n xs = case xs of { [] -> n ; (:) h t -> c h (foldr c n t) }; (++) = \xs ys -> foldr (:) ys xs; unwords xs = case xs of { [] -> "" ; (:) x xt -> x ++ foldr (\a s -> ' ':a ++ s) "" xt }; take n xs = ife (n == 0) [] (case xs of { [] -> [] ; (:) x xt -> x:take (n-1) xt }); length xs = case xs of { [] -> 0 ; (:) x xt -> 1 + length xt }; data Ordering = LT | GT | EQ; intcmp x y = ife (x <= y) (ife (y <= x) EQ LT) GT; flst xs n c = case xs of { [] -> n ; (:) x xt -> c x xt }; eqstrcmp xs ys = flst xs EQ (\x xt -> flst ys undefined (\y yt -> case intcmp x y of { LT -> LT ; GT -> GT ; EQ -> eqstrcmp xt yt })); cmp xs ys = case intcmp (length xs) (length ys) of { LT -> LT ; GT -> GT ; EQ -> eqstrcmp xs ys }; alt xs ys = flst xs ys (\x xt -> flst ys xs (\y yt -> case cmp x y of { LT -> x:alt xt ys ; GT -> y:alt xs yt ; EQ -> x:alt xt yt } )); cat xs ys = flst xs [] (\x xt -> flst ys [] (\y yt -> (x ++ y) : alt (cat [x] yt) (cat xt ys))); clo xs = flst xs [""] (\x xt -> flst x (clo xt) (\_ _ -> "" : cat xs (clo xs))); data Re = Nil | Eps | Sym Char | Clo Re | Cat Re Re | Alt Re Re ; enumR expr = case expr of { Nil -> [] ; Eps -> [""] ; Sym a -> [[a]] ; Clo x -> clo (enumR x) ; Cat x y -> cat (enumR x) (enumR y) ; Alt x y -> alt (enumR x) (enumR y) }; a = Sym 'a'; b = Sym 'b'; sandwich = Cat a (Cat (Clo b) a); even_a = Clo (Alt sandwich b); go stdin = unwords (take 32 (enumR even_a));