@@ -2,19 +2,69 @@ module Data.Profunctor.Star where
22
33import Prelude
44
5- import Data.Tuple (Tuple (..))
5+ import Control.Alt (class Alt , (<|>))
6+ import Control.Alternative (class Alternative )
7+ import Control.MonadPlus (class MonadPlus )
8+ import Control.MonadZero (class MonadZero )
9+ import Control.Plus (class Plus , empty )
10+
11+ import Data.Distributive (class Distributive , distribute , collect )
612import Data.Either (Either (..), either )
13+ import Data.Functor.Invariant (class Invariant , imap )
714import Data.Profunctor (class Profunctor )
8- import Data.Profunctor.Strong (class Strong )
915import Data.Profunctor.Choice (class Choice )
16+ import Data.Profunctor.Closed (class Closed )
17+ import Data.Profunctor.Strong (class Strong )
18+ import Data.Tuple (Tuple (..))
1019
1120-- | `Star` turns a `Functor` into a `Profunctor`.
21+ -- |
22+ -- | `Star f` is also the Kleisli category for `f`
1223newtype Star f a b = Star (a -> f b )
1324
1425-- | Unwrap a value of type `Star f a b`.
1526unStar :: forall f a b . Star f a b -> a -> f b
1627unStar (Star f) = f
1728
29+ instance semigroupoidStar :: Bind f => Semigroupoid (Star f ) where
30+ compose (Star f) (Star g) = Star \x -> g x >>= f
31+
32+ instance categoryStar :: Monad f => Category (Star f ) where
33+ id = Star pure
34+
35+ instance functorStar :: Functor f => Functor (Star f a ) where
36+ map f (Star g) = Star (map f <<< g)
37+
38+ instance invariantStar :: Invariant f => Invariant (Star f a ) where
39+ imap f g (Star h) = Star (imap f g <<< h)
40+
41+ instance applyStar :: Apply f => Apply (Star f a ) where
42+ apply (Star f) (Star g) = Star \a -> f a <*> g a
43+
44+ instance applicativeStar :: Applicative f => Applicative (Star f a ) where
45+ pure a = Star \_ -> pure a
46+
47+ instance bindStar :: Bind f => Bind (Star f a ) where
48+ bind (Star m) f = Star \x -> m x >>= \a -> unStar (f a) x
49+
50+ instance monadStar :: Monad f => Monad (Star f a )
51+
52+ instance altStar :: Alt f => Alt (Star f a ) where
53+ alt (Star f) (Star g) = Star \a -> f a <|> g a
54+
55+ instance plusStar :: Plus f => Plus (Star f a ) where
56+ empty = Star \_ -> empty
57+
58+ instance alternativeStar :: Alternative f => Alternative (Star f a )
59+
60+ instance monadZeroStar :: MonadZero f => MonadZero (Star f a )
61+
62+ instance monadPlusStar :: MonadPlus f => MonadPlus (Star f a )
63+
64+ instance distributiveStar :: Distributive f => Distributive (Star f a ) where
65+ distribute f = Star \a -> collect ((_ $ a) <<< unStar) f
66+ collect f = distribute <<< map f
67+
1868instance profunctorStar :: Functor f => Profunctor (Star f ) where
1969 dimap f g (Star ft) = Star (f >>> ft >>> map g)
2070
@@ -25,3 +75,6 @@ instance strongStar :: Functor f => Strong (Star f) where
2575instance choiceStar :: Applicative f => Choice (Star f ) where
2676 left (Star f) = Star $ either (map Left <<< f) (pure <<< Right )
2777 right (Star f) = Star $ either (pure <<< Left ) (map Right <<< f)
78+
79+ instance closedStar :: Distributive f => Closed (Star f ) where
80+ closed (Star f) = Star \g -> distribute (f <<< g)
0 commit comments