Skip to content

Commit e1e3fd0

Browse files
authored
Merge pull request #96 from purescript/coyoneda-instances
Additional `Coyoneda` instances
2 parents 1faad9d + a6191d2 commit e1e3fd0

File tree

1 file changed

+46
-2
lines changed

1 file changed

+46
-2
lines changed

src/Data/Coyoneda.purs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,21 @@ module Data.Coyoneda
1010

1111
import Prelude
1212

13+
import Control.Alt (class Alt, alt)
14+
import Control.Alternative (class Alternative, class Plus, empty)
1315
import Control.Comonad (class Comonad, extract)
1416
import Control.Extend (class Extend, (<<=))
1517
import Control.Monad.Trans.Class (class MonadTrans)
16-
18+
import Control.MonadPlus (class MonadPlus, class MonadZero)
19+
import Data.Distributive (class Distributive, collect)
1720
import Data.Eq (class Eq1, eq1)
1821
import Data.Exists (Exists, runExists, mkExists)
22+
import Data.Foldable (class Foldable, foldMap, foldl, foldr)
23+
import Data.Functor.Invariant (class Invariant, imapF)
1924
import Data.Ord (class Ord1, compare1)
25+
import Data.Semigroup.Foldable (class Foldable1, foldMap1)
26+
import Data.Semigroup.Traversable (class Traversable1, sequence1, traverse1)
27+
import Data.Traversable (class Traversable, traverse)
2028

2129
-- | `Coyoneda` is encoded as an existential type using `Data.Exists`.
2230
-- |
@@ -56,12 +64,23 @@ instance ord1Coyoneda :: (Functor f, Ord1 f) => Ord1 (Coyoneda f) where
5664
instance functorCoyoneda :: Functor (Coyoneda f) where
5765
map f (Coyoneda e) = runExists (\(CoyonedaF k fi) -> coyoneda (f <<< k) fi) e
5866

67+
instance invatiantCoyoneda :: Invariant (Coyoneda f) where
68+
imap = imapF
69+
5970
instance applyCoyoneda :: Apply f => Apply (Coyoneda f) where
6071
apply f g = liftCoyoneda $ lowerCoyoneda f <*> lowerCoyoneda g
6172

6273
instance applicativeCoyoneda :: Applicative f => Applicative (Coyoneda f) where
6374
pure = liftCoyoneda <<< pure
6475

76+
instance altCoyoneda :: Alt f => Alt (Coyoneda f) where
77+
alt x y = liftCoyoneda $ alt (lowerCoyoneda x) (lowerCoyoneda y)
78+
79+
instance plusCoyoneda :: Plus f => Plus (Coyoneda f) where
80+
empty = liftCoyoneda empty
81+
82+
instance alternativeCoyoneda :: Alternative f => Alternative (Coyoneda f)
83+
6584
instance bindCoyoneda :: Bind f => Bind (Coyoneda f) where
6685
bind (Coyoneda e) f =
6786
liftCoyoneda $
@@ -78,6 +97,10 @@ instance monadCoyoneda :: Monad f => Monad (Coyoneda f)
7897
instance monadTransCoyoneda :: MonadTrans Coyoneda where
7998
lift = liftCoyoneda
8099

100+
instance monadZeroCoyoneda :: MonadZero f => MonadZero (Coyoneda f)
101+
102+
instance monadPlusCoyoneda :: MonadPlus f => MonadPlus (Coyoneda f)
103+
81104
instance extendCoyoneda :: Extend w => Extend (Coyoneda w) where
82105
extend f (Coyoneda e) =
83106
runExists (\(CoyonedaF k fi) -> liftCoyoneda $ f <<< coyoneda k <<= fi) e
@@ -91,14 +114,35 @@ instance extendCoyoneda :: Extend w => Extend (Coyoneda w) where
91114
instance comonadCoyoneda :: Comonad w => Comonad (Coyoneda w) where
92115
extract (Coyoneda e) = runExists (\(CoyonedaF k fi) -> k $ extract fi) e
93116

117+
instance foldableCoyoneda :: Foldable f => Foldable (Coyoneda f) where
118+
foldr f z = unCoyoneda \k -> foldr (f <<< k) z
119+
foldl f z = unCoyoneda \k -> foldl (\x -> f x <<< k) z
120+
foldMap f = unCoyoneda \k -> foldMap (f <<< k)
121+
122+
instance traversableCoyoneda :: Traversable f => Traversable (Coyoneda f) where
123+
traverse f = unCoyoneda \k -> map liftCoyoneda <<< traverse (f <<< k)
124+
sequence = unCoyoneda \k -> map liftCoyoneda <<< traverse k
125+
126+
instance foldable1Coyoneda :: Foldable1 f => Foldable1 (Coyoneda f) where
127+
foldMap1 f = unCoyoneda \k -> foldMap1 (f <<< k)
128+
fold1 = unCoyoneda \k -> foldMap1 k
129+
130+
instance traversable1Coyoneda :: Traversable1 f => Traversable1 (Coyoneda f) where
131+
traverse1 f = unCoyoneda \k -> map liftCoyoneda <<< traverse1 (f <<< k)
132+
sequence1 = unCoyoneda \k -> map liftCoyoneda <<< sequence1 <<< map k
133+
134+
instance distributiveCoyoneda :: Distributive f => Distributive (Coyoneda f) where
135+
collect f = liftCoyoneda <<< collect (lowerCoyoneda <<< f)
136+
distribute = liftCoyoneda <<< collect lowerCoyoneda
137+
94138
-- | Construct a value of type `Coyoneda f b` from a mapping function and a
95139
-- | value of type `f a`.
96140
coyoneda :: forall f a b. (a -> b) -> f a -> Coyoneda f b
97141
coyoneda k fi = Coyoneda $ mkExists $ CoyonedaF k fi
98142

99143
-- | Deconstruct a value of `Coyoneda a` to retrieve the mapping function and
100144
-- | original value.
101-
unCoyoneda :: forall f g a. (forall b. (b -> a) -> f b -> g a) -> Coyoneda f a -> g a
145+
unCoyoneda :: forall f a r. (forall b. (b -> a) -> f b -> r) -> Coyoneda f a -> r
102146
unCoyoneda f (Coyoneda e) = runExists (\(CoyonedaF k fi) -> f k fi) e
103147

104148
-- | Lift a value described by the type constructor `f` to `Coyoneda f`.

0 commit comments

Comments
 (0)