|
1 |
| --- | The _cofree comonad_ for a `Functor`. |
2 |
| - |
3 |
| -module Control.Comonad.Cofree.Compat |
4 |
| - ( Cofree |
5 |
| - , deferCofree |
6 |
| - , mkCofree, (:<) |
7 |
| - , head |
8 |
| - , tail |
9 |
| - , hoistCofree |
10 |
| - , unfoldCofree |
11 |
| - , buildCofree |
12 |
| - , explore |
13 |
| - , exploreM |
| 1 | +module Control.Comonad.Cofree.Class.Compat |
| 2 | + ( class ComonadCofree |
| 3 | + , unwrapCofree |
14 | 4 | ) where
|
15 | 5 |
|
16 | 6 | import Prelude
|
17 |
| -import Control.Alternative (class Alternative, (<|>), empty) |
18 |
| -import Control.Comonad (class Comonad, extract) |
19 |
| -import Control.Extend (class Extend) |
20 |
| -import Control.Lazy as Z |
21 |
| -import Control.Monad.Free.Compat (Free, runFreeM) |
22 |
| -import Control.Monad.Rec.Class (class MonadRec) |
23 |
| -import Control.Monad.State (State, StateT(..), runState, runStateT, state) |
24 |
| -import Data.Eq (class Eq1, eq1) |
25 |
| -import Data.Foldable (class Foldable, foldr, foldl, foldMap) |
26 |
| -import Data.Lazy (Lazy, force, defer) |
27 |
| -import Data.Ord (class Ord1, compare1) |
28 |
| -import Data.Traversable (class Traversable, traverse) |
29 |
| -import Data.Tuple (Tuple(..), fst, snd) |
30 |
| - |
31 |
| --- | The `Cofree` `Comonad` for a functor. |
32 |
| --- | |
33 |
| --- | A value of type `Cofree f a` consists of an `f`-branching |
34 |
| --- | tree, annotated with labels of type `a`. |
35 |
| --- | |
36 |
| --- | The `Comonad` instance supports _redecoration_, recomputing |
37 |
| --- | labels from the local context. |
38 |
| -newtype Cofree f a = Cofree (Lazy (Tuple a (f (Cofree f a)))) |
39 |
| - |
40 |
| --- | Lazily creates a value of type `Cofree f a` from a label and a |
41 |
| --- | functor-full of "subtrees". |
42 |
| -deferCofree :: forall f a. (Unit -> Tuple a (f (Cofree f a))) -> Cofree f a |
43 |
| -deferCofree = Cofree <<< defer |
44 |
| - |
45 |
| --- | Create a value of type `Cofree f a` from a label and a |
46 |
| --- | functor-full of "subtrees". |
47 |
| -mkCofree :: forall f a. a -> f (Cofree f a) -> Cofree f a |
48 |
| -mkCofree a t = Cofree (defer \_ -> Tuple a t) |
49 |
| - |
50 |
| -infixr 5 mkCofree as :< |
51 |
| - |
52 |
| --- | Returns the label for a tree. |
53 |
| -head :: forall f a. Cofree f a -> a |
54 |
| -head (Cofree c) = fst (force c) |
55 |
| - |
56 |
| --- | Returns the "subtrees" of a tree. |
57 |
| -tail :: forall f a. Cofree f a -> f (Cofree f a) |
58 |
| -tail (Cofree c) = snd (force c) |
59 |
| - |
60 |
| -hoistCofree :: forall f g. Functor f => (f ~> g) -> Cofree f ~> Cofree g |
61 |
| -hoistCofree nat (Cofree c) = Cofree (map (nat <<< map (hoistCofree nat)) <$> c) |
62 |
| - |
63 |
| --- | This signature is deprecated and will be replaced by `buildCofree` in a |
64 |
| --- | future release. |
65 |
| -unfoldCofree |
66 |
| - :: forall f s a |
67 |
| - . Functor f |
68 |
| - => (s -> a) |
69 |
| - -> (s -> f s) |
70 |
| - -> s |
71 |
| - -> Cofree f a |
72 |
| -unfoldCofree e n = buildCofree (\s -> Tuple (e s) (n s)) |
73 |
| - |
74 |
| --- | Recursively unfolds a `Cofree` structure given a seed. |
75 |
| -buildCofree |
76 |
| - :: forall f s a |
77 |
| - . Functor f |
78 |
| - => (s -> Tuple a (f s)) |
79 |
| - -> s |
80 |
| - -> Cofree f a |
81 |
| -buildCofree k s = |
82 |
| - Cofree (defer \_ -> map (buildCofree k) <$> k s) |
83 |
| - |
84 |
| --- | Explore a value in the cofree comonad by using an expression in a |
85 |
| --- | corresponding free monad. |
86 |
| --- | |
87 |
| --- | The free monad should be built from a functor which pairs with the |
88 |
| --- | functor underlying the cofree comonad. |
89 |
| -explore |
90 |
| - :: forall f g a b |
91 |
| - . Functor f |
92 |
| - => Functor g |
93 |
| - => (forall x y. f (x -> y) -> g x -> y) |
94 |
| - -> Free f (a -> b) |
95 |
| - -> Cofree g a |
96 |
| - -> b |
97 |
| -explore pair m w = |
98 |
| - case runState (runFreeM step m) w of |
99 |
| - Tuple f cof -> f (extract cof) |
100 |
| - where |
101 |
| - step :: f (Free f (a -> b)) -> State (Cofree g a) (Free f (a -> b)) |
102 |
| - step ff = state \cof -> pair (map Tuple ff) (tail cof) |
103 |
| - |
104 |
| -exploreM |
105 |
| - :: forall f g a b m |
106 |
| - . Functor f |
107 |
| - => Functor g |
108 |
| - => MonadRec m |
109 |
| - => (forall x y. f (x -> y) -> g x -> m y) |
110 |
| - -> Free f (a -> b) |
111 |
| - -> Cofree g a |
112 |
| - -> m b |
113 |
| -exploreM pair m w = |
114 |
| - eval <$> runStateT (runFreeM step m) w |
115 |
| - where |
116 |
| - step :: f (Free f (a -> b)) -> StateT (Cofree g a) m (Free f (a -> b)) |
117 |
| - step ff = StateT \cof -> pair (map Tuple ff) (tail cof) |
118 |
| - |
119 |
| - eval :: forall x y. Tuple (x -> y) (Cofree g x) -> y |
120 |
| - eval (Tuple f cof) = f (extract cof) |
121 |
| - |
122 |
| -instance eqCofree :: (Eq1 f, Eq a) => Eq (Cofree f a) where |
123 |
| - eq x y = head x == head y && tail x `eq1` tail y |
124 |
| - |
125 |
| -instance eq1Cofree :: Eq1 f => Eq1 (Cofree f) where |
126 |
| - eq1 = eq |
127 |
| - |
128 |
| -instance ordCofree :: (Ord1 f, Ord a) => Ord (Cofree f a) where |
129 |
| - compare x y = |
130 |
| - case compare (head x) (head y) of |
131 |
| - EQ -> compare1 (tail x) (tail y) |
132 |
| - r -> r |
133 |
| - |
134 |
| -instance ord1Cofree :: Ord1 f => Ord1 (Cofree f) where |
135 |
| - compare1 = compare |
136 |
| - |
137 |
| -instance functorCofree :: Functor f => Functor (Cofree f) where |
138 |
| - map f = loop |
139 |
| - where |
140 |
| - loop (Cofree fa) = Cofree ((\(Tuple a b) -> Tuple (f a) (loop <$> b)) <$> fa) |
141 |
| - |
142 |
| -instance foldableCofree :: Foldable f => Foldable (Cofree f) where |
143 |
| - foldr f = flip go |
144 |
| - where |
145 |
| - go fa b = f (head fa) (foldr go b (tail fa)) |
146 |
| - |
147 |
| - foldl f = go |
148 |
| - where |
149 |
| - go b fa = foldl go (f b (head fa)) (tail fa) |
150 |
| - |
151 |
| - foldMap f = go |
152 |
| - where |
153 |
| - go fa = f (head fa) <> (foldMap go (tail fa)) |
154 |
| - |
155 |
| -instance traversableCofree :: Traversable f => Traversable (Cofree f) where |
156 |
| - sequence = traverse identity |
157 |
| - traverse f = loop |
158 |
| - where |
159 |
| - loop ta = mkCofree <$> f (head ta) <*> (traverse loop (tail ta)) |
160 |
| - |
161 |
| -instance extendCofree :: Functor f => Extend (Cofree f) where |
162 |
| - extend f = loop |
163 |
| - where |
164 |
| - loop (Cofree fa) = Cofree ((\(Tuple a b) -> Tuple (f (Cofree fa)) (loop <$> b)) <$> fa) |
165 | 7 |
|
166 |
| -instance comonadCofree :: Functor f => Comonad (Cofree f) where |
167 |
| - extract = head |
| 8 | +import Control.Comonad (class Comonad) |
| 9 | +import Control.Comonad.Cofree.Compat (Cofree, tail) |
| 10 | +import Control.Comonad.Env.Trans (EnvT(..)) |
| 11 | +import Control.Comonad.Store.Trans (StoreT(..)) |
| 12 | +import Control.Comonad.Traced.Trans (TracedT(..)) |
| 13 | +import Data.Tuple (Tuple(..)) |
168 | 14 |
|
169 |
| -instance applyCofree :: Alternative f => Apply (Cofree f) where |
170 |
| - apply = ap |
| 15 | +-- | Based on <http://hackage.haskell.org/package/free/docs/Control-Comonad-Cofree-Class.html> |
| 16 | +class (Functor f, Comonad w) <= ComonadCofree f w | w -> f where |
| 17 | + unwrapCofree :: forall a. w a -> f (w a) |
171 | 18 |
|
172 |
| -instance applicativeCofree :: Alternative f => Applicative (Cofree f) where |
173 |
| - pure a = mkCofree a empty |
| 19 | +instance comonadCofreeCofree :: Functor f => ComonadCofree f (Cofree f) where |
| 20 | + unwrapCofree = tail |
174 | 21 |
|
175 |
| -instance bindCofree :: Alternative f => Bind (Cofree f) where |
176 |
| - bind fa f = loop fa |
177 |
| - where |
178 |
| - loop fa' = |
179 |
| - let fh = f (head fa') |
180 |
| - in mkCofree (head fh) ((tail fh) <|> (loop <$> tail fa')) |
| 22 | +instance comonadCofreeEnvT :: (Functor f, ComonadCofree f w) => ComonadCofree f (EnvT e w) where |
| 23 | + unwrapCofree (EnvT (Tuple e wa)) = map (\x -> EnvT (Tuple e x)) (unwrapCofree wa) |
181 | 24 |
|
182 |
| -instance monadCofree :: Alternative f => Monad (Cofree f) |
| 25 | +instance comonadCofreeStoreT :: (Functor f, ComonadCofree f w) => ComonadCofree f (StoreT s w) where |
| 26 | + unwrapCofree (StoreT (Tuple wsa s)) = map (\x -> StoreT (Tuple x s)) (unwrapCofree wsa) |
183 | 27 |
|
184 |
| -instance lazyCofree :: Z.Lazy (Cofree f a) where |
185 |
| - defer k = Cofree (defer \_ -> let (Cofree t) = k unit in force t) |
| 28 | +instance comonadCofreeTracedT :: (Functor f, ComonadCofree f w, Monoid m) => ComonadCofree f (TracedT m w) where |
| 29 | + unwrapCofree (TracedT wma) = map TracedT (unwrapCofree wma) |
0 commit comments