2
2
3
3
module Control.Comonad.Cofree
4
4
( Cofree
5
+ , deferCofree
5
6
, mkCofree , (:<)
6
7
, head
7
8
, tail
8
9
, hoistCofree
9
10
, unfoldCofree
11
+ , buildCofree
10
12
, explore
11
13
, exploreM
12
14
) where
@@ -15,6 +17,7 @@ import Prelude
15
17
import Control.Alternative (class Alternative , (<|>), empty )
16
18
import Control.Comonad (class Comonad , extract )
17
19
import Control.Extend (class Extend )
20
+ import Control.Lazy as Z
18
21
import Control.Monad.Free (Free , runFreeM )
19
22
import Control.Monad.Rec.Class (class MonadRec )
20
23
import Control.Monad.State (State , StateT (..), runState , runStateT , state )
@@ -23,7 +26,7 @@ import Data.Foldable (class Foldable, foldr, foldl, foldMap)
23
26
import Data.Lazy (Lazy , force , defer )
24
27
import Data.Ord (class Ord1 , compare1 )
25
28
import Data.Traversable (class Traversable , traverse )
26
- import Data.Tuple (Tuple (..))
29
+ import Data.Tuple (Tuple (..), fst , snd )
27
30
28
31
-- | The `Cofree` `Comonad` for a functor.
29
32
-- |
@@ -32,41 +35,51 @@ import Data.Tuple (Tuple(..))
32
35
-- |
33
36
-- | The `Comonad` instance supports _redecoration_, recomputing
34
37
-- | labels from the local context.
35
- data Cofree f a = Cofree a (Lazy (f (Cofree f a )))
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
36
44
37
45
-- | Create a value of type `Cofree f a` from a label and a
38
46
-- | functor-full of "subtrees".
39
47
mkCofree :: forall f a . a -> f (Cofree f a ) -> Cofree f a
40
- mkCofree a t = Cofree a (defer \_ -> t)
48
+ mkCofree a t = Cofree (defer \_ -> Tuple a t)
41
49
42
50
infixr 5 mkCofree as :<
43
51
44
52
-- | Returns the label for a tree.
45
53
head :: forall f a . Cofree f a -> a
46
- head (Cofree h _ ) = h
54
+ head (Cofree c ) = fst (force c)
47
55
48
56
-- | Returns the "subtrees" of a tree.
49
57
tail :: forall f a . Cofree f a -> f (Cofree f a )
50
- tail (Cofree _ t) = force t
51
-
52
- _tail :: forall f a . Cofree f a -> Lazy (f (Cofree f a ))
53
- _tail (Cofree _ t) = t
54
-
55
- _lift :: forall f a b . Functor f => (a -> b ) -> Lazy (f a ) -> Lazy (f b )
56
- _lift = map <<< map
58
+ tail (Cofree c) = snd (force c)
57
59
58
60
hoistCofree :: forall f g . Functor f => (f ~> g ) -> Cofree f ~> Cofree g
59
- hoistCofree nat cf = head cf :< nat (hoistCofree nat <$> tail cf )
61
+ hoistCofree nat ( Cofree c) = Cofree (map (nat <<< map (hoistCofree nat)) <$> c )
60
62
63
+ -- | This signature is deprecated and will be replaced by `buildCofree` in a
64
+ -- | future release.
61
65
unfoldCofree
62
66
:: forall f s a
63
67
. Functor f
64
68
=> (s -> a )
65
69
-> (s -> f s )
66
70
-> s
67
71
-> Cofree f a
68
- unfoldCofree e n s =
69
- Cofree (e s) (defer \_ -> unfoldCofree e n <$> n s)
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)
70
83
71
84
-- | Explore a value in the cofree comonad by using an expression in a
72
85
-- | corresponding free monad.
@@ -122,8 +135,9 @@ instance ord1Cofree :: Ord1 f => Ord1 (Cofree f) where
122
135
compare1 = compare
123
136
124
137
instance functorCofree :: Functor f => Functor (Cofree f ) where
125
- map f = loop where
126
- loop fa = Cofree (f (head fa)) (_lift loop (_tail fa))
138
+ map f = loop
139
+ where
140
+ loop (Cofree fa) = Cofree ((\(Tuple a b) -> Tuple (f a) (loop <$> b)) <$> fa)
127
141
128
142
instance foldableCofree :: Foldable f => Foldable (Cofree f ) where
129
143
foldr f = flip go
@@ -147,7 +161,7 @@ instance traversableCofree :: Traversable f => Traversable (Cofree f) where
147
161
instance extendCofree :: Functor f => Extend (Cofree f ) where
148
162
extend f = loop
149
163
where
150
- loop fa = Cofree (f fa) (_lift loop (_tail fa) )
164
+ loop ( Cofree fa) = Cofree ((\( Tuple a b) -> Tuple (f ( Cofree fa)) ( loop <$> b)) <$> fa )
151
165
152
166
instance comonadCofree :: Functor f => Comonad (Cofree f ) where
153
167
extract = head
@@ -166,3 +180,6 @@ instance bindCofree :: Alternative f => Bind (Cofree f) where
166
180
in mkCofree (head fh) ((tail fh) <|> (loop <$> tail fa'))
167
181
168
182
instance monadCofree :: Alternative f => Monad (Cofree f )
183
+
184
+ instance lazyCofree :: Z.Lazy (Cofree f a ) where
185
+ defer k = Cofree (defer \_ -> let (Cofree t) = k unit in force t)
0 commit comments