Skip to content

Commit 6180532

Browse files
Trim compat modules by relying on new implementations
1 parent 7e832f5 commit 6180532

File tree

5 files changed

+151
-431
lines changed

5 files changed

+151
-431
lines changed

src/Control/Comonad/Cofree.purs

Lines changed: 138 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,87 @@
11
-- | The _cofree comonad_ for a `Functor`.
22

33
module Control.Comonad.Cofree
4-
( module Control.Comonad.Cofree.Compat
4+
( Cofree
5+
, deferCofree
6+
, mkCofree
7+
, (:<)
8+
, head
9+
, tail
10+
, hoistCofree
11+
, unfoldCofree
12+
, buildCofree
513
, explore
614
, exploreM
715
) where
816

9-
import Control.Comonad.Cofree.Compat hiding (explore, exploreM)
17+
import Prelude
1018

11-
import Prelude (class Functor, map, (<$>))
12-
import Control.Comonad (extract)
19+
import Control.Alternative (class Alternative, (<|>), empty)
20+
import Control.Comonad (class Comonad, extract)
21+
import Control.Extend (class Extend)
22+
import Control.Lazy as Z
1323
import Control.Monad.Free (Free, runRec)
1424
import Control.Monad.Rec.Class (class MonadRec)
1525
import Control.Monad.State (State, StateT(..), runState, runStateT, state)
16-
import Data.Tuple (Tuple(..))
26+
import Data.Eq (class Eq1, eq1)
27+
import Data.Foldable (class Foldable, foldr, foldl, foldMap)
28+
import Data.Lazy (Lazy, force, defer)
29+
import Data.Ord (class Ord1, compare1)
30+
import Data.Traversable (class Traversable, traverse)
31+
import Data.Tuple (Tuple(..), fst, snd)
32+
33+
-- | The `Cofree` `Comonad` for a functor.
34+
-- |
35+
-- | A value of type `Cofree f a` consists of an `f`-branching
36+
-- | tree, annotated with labels of type `a`.
37+
-- |
38+
-- | The `Comonad` instance supports _redecoration_, recomputing
39+
-- | labels from the local context.
40+
newtype Cofree f a = Cofree (Lazy (Tuple a (f (Cofree f a))))
41+
42+
-- | Lazily creates a value of type `Cofree f a` from a label and a
43+
-- | functor-full of "subtrees".
44+
deferCofree :: forall f a. (Unit -> Tuple a (f (Cofree f a))) -> Cofree f a
45+
deferCofree = Cofree <<< defer
46+
47+
-- | Create a value of type `Cofree f a` from a label and a
48+
-- | functor-full of "subtrees".
49+
mkCofree :: forall f a. a -> f (Cofree f a) -> Cofree f a
50+
mkCofree a t = Cofree (defer \_ -> Tuple a t)
51+
52+
infixr 5 mkCofree as :<
53+
54+
-- | Returns the label for a tree.
55+
head :: forall f a. Cofree f a -> a
56+
head (Cofree c) = fst (force c)
57+
58+
-- | Returns the "subtrees" of a tree.
59+
tail :: forall f a. Cofree f a -> f (Cofree f a)
60+
tail (Cofree c) = snd (force c)
61+
62+
hoistCofree :: forall f g. Functor f => (f ~> g) -> Cofree f ~> Cofree g
63+
hoistCofree nat (Cofree c) = Cofree (map (nat <<< map (hoistCofree nat)) <$> c)
64+
65+
-- | This signature is deprecated and will be replaced by `buildCofree` in a
66+
-- | future release.
67+
unfoldCofree
68+
:: forall f s a
69+
. Functor f
70+
=> (s -> a)
71+
-> (s -> f s)
72+
-> s
73+
-> Cofree f a
74+
unfoldCofree e n = buildCofree (\s -> Tuple (e s) (n s))
75+
76+
-- | Recursively unfolds a `Cofree` structure given a seed.
77+
buildCofree
78+
:: forall f s a
79+
. Functor f
80+
=> (s -> Tuple a (f s))
81+
-> s
82+
-> Cofree f a
83+
buildCofree k s =
84+
Cofree (defer \_ -> map (buildCofree k) <$> k s)
1785

1886
-- | Explore a value in the cofree comonad by using an expression in a
1987
-- | corresponding free monad.
@@ -52,3 +120,68 @@ exploreM pair m w =
52120

53121
eval :: forall x y. Tuple (x -> y) (Cofree g x) -> y
54122
eval (Tuple f cof) = f (extract cof)
123+
124+
instance eqCofree :: (Eq1 f, Eq a) => Eq (Cofree f a) where
125+
eq x y = head x == head y && tail x `eq1` tail y
126+
127+
instance eq1Cofree :: Eq1 f => Eq1 (Cofree f) where
128+
eq1 = eq
129+
130+
instance ordCofree :: (Ord1 f, Ord a) => Ord (Cofree f a) where
131+
compare x y =
132+
case compare (head x) (head y) of
133+
EQ -> compare1 (tail x) (tail y)
134+
r -> r
135+
136+
instance ord1Cofree :: Ord1 f => Ord1 (Cofree f) where
137+
compare1 = compare
138+
139+
instance functorCofree :: Functor f => Functor (Cofree f) where
140+
map f = loop
141+
where
142+
loop (Cofree fa) = Cofree ((\(Tuple a b) -> Tuple (f a) (loop <$> b)) <$> fa)
143+
144+
instance foldableCofree :: Foldable f => Foldable (Cofree f) where
145+
foldr f = flip go
146+
where
147+
go fa b = f (head fa) (foldr go b (tail fa))
148+
149+
foldl f = go
150+
where
151+
go b fa = foldl go (f b (head fa)) (tail fa)
152+
153+
foldMap f = go
154+
where
155+
go fa = f (head fa) <> (foldMap go (tail fa))
156+
157+
instance traversableCofree :: Traversable f => Traversable (Cofree f) where
158+
sequence = traverse identity
159+
traverse f = loop
160+
where
161+
loop ta = mkCofree <$> f (head ta) <*> (traverse loop (tail ta))
162+
163+
instance extendCofree :: Functor f => Extend (Cofree f) where
164+
extend f = loop
165+
where
166+
loop (Cofree fa) = Cofree ((\(Tuple a b) -> Tuple (f (Cofree fa)) (loop <$> b)) <$> fa)
167+
168+
instance comonadCofree :: Functor f => Comonad (Cofree f) where
169+
extract = head
170+
171+
instance applyCofree :: Alternative f => Apply (Cofree f) where
172+
apply = ap
173+
174+
instance applicativeCofree :: Alternative f => Applicative (Cofree f) where
175+
pure a = mkCofree a empty
176+
177+
instance bindCofree :: Alternative f => Bind (Cofree f) where
178+
bind fa f = loop fa
179+
where
180+
loop fa' =
181+
let fh = f (head fa')
182+
in mkCofree (head fh) ((tail fh) <|> (loop <$> tail fa'))
183+
184+
instance monadCofree :: Alternative f => Monad (Cofree f)
185+
186+
instance lazyCofree :: Z.Lazy (Cofree f a) where
187+
defer k = Cofree (defer \_ -> let (Cofree t) = k unit in force t)

src/Control/Comonad/Cofree/Compat.purs

Lines changed: 0 additions & 185 deletions
This file was deleted.

src/Control/Monad/Free/Class/Compat.purs

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)