pandora-0.4.6: Pandora/Paradigm/Primary/Algebraic.hs
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Pandora.Paradigm.Primary.Algebraic (module Exports, Applicative_, Alternative_, Extractable_, ($>-), ($$>-), ($$$>-), (-<*>-), (*>-), forever_, (-+-), void, empty, point, extract) where
import Pandora.Paradigm.Primary.Algebraic.Exponential as Exports
import Pandora.Paradigm.Primary.Algebraic.Product as Exports
import Pandora.Paradigm.Primary.Algebraic.Sum as Exports
import Pandora.Paradigm.Primary.Algebraic.Zero as Exports
import Pandora.Paradigm.Primary.Algebraic.One as Exports
import Pandora.Pattern.Category (($))
import Pandora.Pattern.Functor.Covariant (Covariant ((-<$>-)), (-<$$>-), (-<$$$>-))
import Pandora.Pattern.Functor.Semimonoidal (Semimonoidal (multiply))
import Pandora.Pattern.Functor.Monoidal (Monoidal (unit), Unit)
import Pandora.Pattern.Functor.Comonad (Comonad)
import Pandora.Pattern.Functor.Traversable (Traversable ((<<-)))
import Pandora.Pattern.Functor.Adjoint (Adjoint ((-|), (|-)))
import Pandora.Paradigm.Primary.Functor.Proxy (Proxy (Proxy))
import Pandora.Paradigm.Primary.Transformer.Flip (Flip (Flip))
type instance Unit (:*:) = One
type instance Unit (:+:) = Zero
infixl 4 -<*>-
($>-) :: Covariant (->) (->) t => t a -> b -> t b
x $>- r = (r !.) -<$>- x
($$>-) :: (Covariant (->) (->) t, Covariant (->) (->) u) => t (u a) -> b -> t (u b)
x $$>- r = (r !.) -<$$>- x
($$$>-) :: (Covariant (->) (->) t, Covariant (->) (->) u, Covariant (->) (->) v) => t (u (v a)) -> b -> t (u (v b))
x $$$>- r = (r !.) -<$$$>- x
void :: Covariant (->) (->) t => t a -> t ()
void x = x $>- ()
instance Traversable (->) (->) ((:*:) s) where
f <<- x = (attached x :*:) -<$>- f (extract x)
instance Adjoint (->) (->) ((:*:) s) ((->) s) where
(-|) :: ((s :*: a) -> b) -> a -> (s -> b)
f -| x = \s -> f $ s :*: x
(|-) :: (a -> s -> b) -> (s :*: a) -> b
f |- ~(s :*: x) = f x s
instance Semimonoidal (->) (:*:) (:*:) ((->) e) where
multiply :: ((e -> a) :*: (e -> b)) -> e -> (a :*: b)
multiply (g :*: h) = \x -> g x :*: h x
instance Semimonoidal (<--) (:*:) (:*:) ((->) e) where
multiply = Flip $ \f -> (\e -> attached $ f e) :*: (\e -> extract $ f e)
instance Semimonoidal (->) (:*:) (:+:) ((:+:) e) where
multiply :: ((e :+: a) :*: (e :+: b)) -> e :+: a :+: b
multiply (Option _ :*: Option e') = Option e'
multiply (Option _ :*: Adoption y) = Adoption $ Adoption y
multiply (Adoption x :*: _) = Adoption $ Option x
instance Semimonoidal (->) (:*:) (:*:) ((:+:) e) where
multiply (Adoption x :*: Adoption y) = Adoption $ x :*: y
multiply (Option e :*: _) = Option e
multiply (_ :*: Option e) = Option e
instance Monoidal (->) (->) (:*:) (:*:) ((:+:) e) where
unit _ f = Adoption $ f One
instance Semimonoidal (<--) (:*:) (:*:) ((:*:) s) where
multiply = Flip $ \(s :*: x :*: y) -> (s :*: x) :*: (s :*: y)
instance Monoidal (<--) (->) (:*:) (:*:) ((:*:) s) where
unit _ = Flip $ \(_ :*: x) -> (\_ -> x)
instance Comonad ((:*:) s) (->) where
instance Semimonoidal (<--) (:*:) (:*:) (Flip (:*:) a) where
multiply = Flip $ \(Flip ((sx :*: sy) :*: r)) -> Flip (sx :*: r) :*: Flip (sy :*: r)
instance Monoidal (<--) (->) (:*:) (:*:) (Flip (:*:) a) where
unit _ = Flip $ \(Flip (s :*: _)) -> (\_ -> s)
type Applicative_ t = (Covariant (->) (->) t, Semimonoidal (->) (:*:) (:*:) t, Monoidal (->) (->) (:*:) (:*:) t)
type Alternative_ t = (Covariant (->) (->) t, Semimonoidal (->) (:*:) (:+:) t, Monoidal (->) (->) (:*:) (:+:) t)
(-<*>-) :: (Covariant (->) (->) t, Semimonoidal (->) (:*:) (:*:) t)
=> t (a -> b) -> t a -> t b
f -<*>- x = (|-) @(->) @(->) (&) -<$>- multiply @_ @_ @(:*:) (f :*: x)
forever_ :: (Covariant (->) (->) t, Semimonoidal (->) (:*:) (:*:) t) => t a -> t b
forever_ x = let r = x *>- r in r
(*>-) :: (Covariant (->) (->) t, Semimonoidal (->) (:*:) (:*:) t) => t a -> t b -> t b
x *>- y = ((!.) %) -<$>- x -<*>- y
(-+-) :: (Covariant (->) (->) t, Semimonoidal (->) (:*:) (:+:) t)
=> t a -> t b -> (a :+: b -> r) -> t r
x -+- y = \f -> f -<$>- multiply (x :*: y)
point :: Monoidal (->) (->) (:*:) (:*:) t => a -> t a
point x = unit (Proxy @(:*:)) (\One -> x)
empty :: Monoidal (->) (->) (:*:) (:+:) t => t a
empty = unit (Proxy @(:*:)) absurd
type Extractable_ t = Monoidal (<--) (->) (:*:) (:*:) t
extract :: Extractable_ t => t a -> a
extract j = let Flip f = unit @(<--) @(->) @(:*:) @(:*:) Proxy in f j $ One