@@ -10,13 +10,21 @@ module Data.Coyoneda
10
10
11
11
import Prelude
12
12
13
+ import Control.Alt (class Alt , alt )
14
+ import Control.Alternative (class Alternative , class Plus , empty )
13
15
import Control.Comonad (class Comonad , extract )
14
16
import Control.Extend (class Extend , (<<=))
15
17
import Control.Monad.Trans.Class (class MonadTrans )
16
-
18
+ import Control.MonadPlus (class MonadPlus , class MonadZero )
19
+ import Data.Distributive (class Distributive , collect )
17
20
import Data.Eq (class Eq1 , eq1 )
18
21
import Data.Exists (Exists , runExists , mkExists )
22
+ import Data.Foldable (class Foldable , foldMap , foldl , foldr )
23
+ import Data.Functor.Invariant (class Invariant , imapF )
19
24
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 )
20
28
21
29
-- | `Coyoneda` is encoded as an existential type using `Data.Exists`.
22
30
-- |
@@ -56,12 +64,23 @@ instance ord1Coyoneda :: (Functor f, Ord1 f) => Ord1 (Coyoneda f) where
56
64
instance functorCoyoneda :: Functor (Coyoneda f ) where
57
65
map f (Coyoneda e) = runExists (\(CoyonedaF k fi) -> coyoneda (f <<< k) fi) e
58
66
67
+ instance invatiantCoyoneda :: Invariant (Coyoneda f ) where
68
+ imap = imapF
69
+
59
70
instance applyCoyoneda :: Apply f => Apply (Coyoneda f ) where
60
71
apply f g = liftCoyoneda $ lowerCoyoneda f <*> lowerCoyoneda g
61
72
62
73
instance applicativeCoyoneda :: Applicative f => Applicative (Coyoneda f ) where
63
74
pure = liftCoyoneda <<< pure
64
75
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
+
65
84
instance bindCoyoneda :: Bind f => Bind (Coyoneda f ) where
66
85
bind (Coyoneda e) f =
67
86
liftCoyoneda $
@@ -78,6 +97,10 @@ instance monadCoyoneda :: Monad f => Monad (Coyoneda f)
78
97
instance monadTransCoyoneda :: MonadTrans Coyoneda where
79
98
lift = liftCoyoneda
80
99
100
+ instance monadZeroCoyoneda :: MonadZero f => MonadZero (Coyoneda f )
101
+
102
+ instance monadPlusCoyoneda :: MonadPlus f => MonadPlus (Coyoneda f )
103
+
81
104
instance extendCoyoneda :: Extend w => Extend (Coyoneda w ) where
82
105
extend f (Coyoneda e) =
83
106
runExists (\(CoyonedaF k fi) -> liftCoyoneda $ f <<< coyoneda k <<= fi) e
@@ -91,14 +114,35 @@ instance extendCoyoneda :: Extend w => Extend (Coyoneda w) where
91
114
instance comonadCoyoneda :: Comonad w => Comonad (Coyoneda w ) where
92
115
extract (Coyoneda e) = runExists (\(CoyonedaF k fi) -> k $ extract fi) e
93
116
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
+
94
138
-- | Construct a value of type `Coyoneda f b` from a mapping function and a
95
139
-- | value of type `f a`.
96
140
coyoneda :: forall f a b . (a -> b ) -> f a -> Coyoneda f b
97
141
coyoneda k fi = Coyoneda $ mkExists $ CoyonedaF k fi
98
142
99
143
-- | Deconstruct a value of `Coyoneda a` to retrieve the mapping function and
100
144
-- | 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
102
146
unCoyoneda f (Coyoneda e) = runExists (\(CoyonedaF k fi) -> f k fi) e
103
147
104
148
-- | Lift a value described by the type constructor `f` to `Coyoneda f`.
0 commit comments