5 | module Data.Enumerate
8 | import Data.Description.Regular
11 | import Data.Enumerate.Common
22 | record Enumerator (a, b : Type) where
23 | constructor MkEnumerator
24 | runEnumerator : List a -> List b
31 | Functor (Enumerator a) where
32 | map f (MkEnumerator enum) = MkEnumerator (\ as => f <$> enum as)
37 | pairWith : (b -> c -> d) -> Enumerator a b -> Enumerator a c -> Enumerator a d
38 | pairWith f (MkEnumerator e1) (MkEnumerator e2)
39 | = MkEnumerator (\ as => prodWith f (e1 as) (e2 as)) where
42 | pair : Enumerator a b -> Enumerator a c -> Enumerator a (b, c)
46 | Applicative (Enumerator a) where
47 | pure = MkEnumerator . const . pure
48 | (<*>) = pairWith ($)
51 | Monad (Enumerator a) where
52 | xs >>= ks = MkEnumerator $
\ as =>
53 | foldr (\ x => interleave (runEnumerator (ks x) as)) []
54 | (runEnumerator xs as)
57 | Alternative (Enumerator a) where
58 | empty = MkEnumerator (const [])
59 | MkEnumerator e1 <|> MkEnumerator e2 = MkEnumerator (\ as => interleave (e1 as) (e2 as))
63 | const : List b -> Enumerator a b
64 | const = MkEnumerator . const
69 | rec : Enumerator a a
70 | rec = MkEnumerator id
74 | data Tree : Type where
76 | Node : Tree -> Tree -> Tree
78 | tree : Enumerator Tree Tree
79 | tree = pure Leaf <|> Node <$> rec <*> rec
88 | sized : Enumerator a a -> Nat -> List a
89 | sized (MkEnumerator enum) = go where
93 | go (S n) = enum (go n)
98 | stream : Enumerator a a -> Stream (List a)
99 | stream (MkEnumerator enum) = iterate enum []
106 | regular : (d : Desc List) -> Enumerator (Fix d) (Fix d)
107 | regular d = MkFix <$> go d where
109 | go : (e : Desc List) -> Enumerator (Fix d) (Elem e (Fix d))
113 | go (Const s prop) = const prop
114 | go (d1 * d2) = pair (go d1) (go d2)
115 | go (d1 + d2) = Left <$> go d1 <|> Right <$> go d2
119 | ListD : List a -> Desc List
120 | ListD as = One + (Const a as * Id)
122 | lists : (xs : List a) -> Nat -> List (Fix (ListD xs))
123 | lists xs = sized (regular (ListD xs))
125 | encode : {0 xs : List a} -> List a -> Fix (ListD xs)
126 | encode = foldr (\x, xs => MkFix (Right (x, xs))) (MkFix (Left ()))
128 | decode : {xs : List a} -> Fix (ListD xs) -> List a
129 | decode = fold (either (const []) (uncurry (::)))
132 | abs : List (List Char)
133 | abs = decode <$> lists ['a', 'b'] 3