@@ -6,16 +6,17 @@ module Control.Comonad.Cofree
6
6
, head
7
7
, tail
8
8
, hoistCofree
9
+ , unfoldCofree
9
10
) where
10
11
11
12
import Prelude
12
13
13
- import Control.Comonad (class Comonad )
14
14
import Control.Alternative (class Alternative , (<|>), empty )
15
+ import Control.Comonad (class Comonad )
15
16
import Control.Extend (class Extend )
16
- import Control.Monad.Trampoline (Trampoline , runTrampoline )
17
17
18
18
import Data.Foldable (class Foldable , foldr , foldl , foldMap )
19
+ import Data.Lazy (Lazy , force , defer )
19
20
import Data.Traversable (class Traversable , traverse )
20
21
21
22
-- | The `Cofree` `Comonad` for a functor.
@@ -25,12 +26,12 @@ import Data.Traversable (class Traversable, traverse)
25
26
-- |
26
27
-- | The `Comonad` instance supports _redecoration_, recomputing
27
28
-- | labels from the local context.
28
- data Cofree f a = Cofree a (Trampoline (f (Cofree f a )))
29
+ data Cofree f a = Cofree a (Lazy (f (Cofree f a )))
29
30
30
31
-- | Create a value of type `Cofree f a` from a label and a
31
32
-- | functor-full of "subtrees".
32
- mkCofree :: forall f a . a -> ( f (Cofree f a ) ) -> Cofree f a
33
- mkCofree a t = Cofree a (pure t)
33
+ mkCofree :: forall f a . a -> f (Cofree f a ) -> Cofree f a
34
+ mkCofree a t = Cofree a (defer \_ -> t)
34
35
35
36
infixr 5 mkCofree as :<
36
37
@@ -40,17 +41,27 @@ head (Cofree h _) = h
40
41
41
42
-- | Returns the "subtrees" of a tree.
42
43
tail :: forall f a . Cofree f a -> f (Cofree f a )
43
- tail (Cofree _ t) = runTrampoline t
44
+ tail (Cofree _ t) = force t
44
45
45
- _tail :: forall f a . Cofree f a -> Trampoline (f (Cofree f a ))
46
+ _tail :: forall f a . Cofree f a -> Lazy (f (Cofree f a ))
46
47
_tail (Cofree _ t) = t
47
48
48
- _lift :: forall f a b . Functor f => (a -> b ) -> Trampoline (f a ) -> Trampoline (f b )
49
+ _lift :: forall f a b . Functor f => (a -> b ) -> Lazy (f a ) -> Lazy (f b )
49
50
_lift = map <<< map
50
51
51
52
hoistCofree :: forall f g . Functor f => (f ~> g ) -> Cofree f ~> Cofree g
52
53
hoistCofree nat cf = head cf :< nat (hoistCofree nat <$> tail cf)
53
54
55
+ unfoldCofree
56
+ :: forall f s a
57
+ . Functor f
58
+ => s
59
+ -> (s -> a )
60
+ -> (s -> f s )
61
+ -> Cofree f a
62
+ unfoldCofree s e n =
63
+ Cofree (e s) (defer \_ -> map (\s1 -> unfoldCofree s1 e n) (n s))
64
+
54
65
instance functorCofree :: Functor f => Functor (Cofree f ) where
55
66
map f = loop where
56
67
loop fa = Cofree (f (head fa)) (_lift loop (_tail fa))
0 commit comments