Skip to content

Commit 3cb6465

Browse files
authored
Merge pull request #59 from purescript/unfold-cofree-2
Unfold cofree 2
2 parents 524e71e + c16fcf4 commit 3cb6465

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

src/Control/Comonad/Cofree.purs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@ module Control.Comonad.Cofree
66
, head
77
, tail
88
, hoistCofree
9+
, unfoldCofree
910
) where
1011

1112
import Prelude
1213

13-
import Control.Comonad (class Comonad)
1414
import Control.Alternative (class Alternative, (<|>), empty)
15+
import Control.Comonad (class Comonad)
1516
import Control.Extend (class Extend)
16-
import Control.Monad.Trampoline (Trampoline, runTrampoline)
1717

1818
import Data.Foldable (class Foldable, foldr, foldl, foldMap)
19+
import Data.Lazy (Lazy, force, defer)
1920
import Data.Traversable (class Traversable, traverse)
2021

2122
-- | The `Cofree` `Comonad` for a functor.
@@ -25,12 +26,12 @@ import Data.Traversable (class Traversable, traverse)
2526
-- |
2627
-- | The `Comonad` instance supports _redecoration_, recomputing
2728
-- | 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)))
2930

3031
-- | Create a value of type `Cofree f a` from a label and a
3132
-- | 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)
3435

3536
infixr 5 mkCofree as :<
3637

@@ -40,17 +41,27 @@ head (Cofree h _) = h
4041

4142
-- | Returns the "subtrees" of a tree.
4243
tail :: forall f a. Cofree f a -> f (Cofree f a)
43-
tail (Cofree _ t) = runTrampoline t
44+
tail (Cofree _ t) = force t
4445

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))
4647
_tail (Cofree _ t) = t
4748

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)
4950
_lift = map <<< map
5051

5152
hoistCofree :: forall f g. Functor f => (f ~> g) -> Cofree f ~> Cofree g
5253
hoistCofree nat cf = head cf :< nat (hoistCofree nat <$> tail cf)
5354

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+
5465
instance functorCofree :: Functor f => Functor (Cofree f) where
5566
map f = loop where
5667
loop fa = Cofree (f (head fa)) (_lift loop (_tail fa))

0 commit comments

Comments
 (0)