{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE UnicodeSyntax #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ExplicitNamespaces #-}
{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ >= 800
{-# LANGUAGE UndecidableSuperClasses #-}
#endif
{-# LANGUAGE LambdaCase #-}
module Control.Category.Constrained (
Category (..)
, Cartesian (..), ObjectPair
, Curry (..), ObjectMorphism
, type (+)()
, CoCartesian (..), ObjectSum
, type Hask
, Isomorphic (..)
, ConstrainedCategory (ConstrainedMorphism)
, type (⊢)()
, constrained, unconstrained
, ConstrainedFunction
, HasAgent (..)
, genericAlg, genericAgentMap
, GenericAgent (..)
, inCategoryOf
, CatTagged
) where
import Prelude hiding (id, (.), curry, uncurry)
import qualified Prelude
import GHC.Exts (Constraint)
import Data.Tagged
import Data.Monoid
import Data.Void
#if MIN_VERSION_base(4,9,0)
import Data.Kind (Type)
#endif
import Data.Type.Coercion
import qualified Control.Category as Hask
import qualified Data.Functor.Contravariant as Hask (Op(..))
import Data.Constraint.Trivial (Unconstrained)
import Control.Category.Discrete
#if MIN_VERSION_base(4,9,0)
class Category (k :: κ -> κ -> Type) where
#else
class Category (k :: κ -> κ -> *) where
#endif
type Object k (o :: κ) :: Constraint
type Object k o = ()
id :: Object k a => k a a
(.) :: (Object k a, Object k b, Object k c)
=> k b c -> k a b -> k a c
infixr 9 .
instance Category Discrete where
id :: Discrete a a
id = Discrete a a
forall k (a :: k). Discrete a a
Refl
Discrete b c
Refl . :: Discrete b c -> Discrete a b -> Discrete a c
. Discrete a b
Refl = Discrete a c
forall k (a :: k). Discrete a a
Refl
instance Category (->) where
id :: a -> a
id = a -> a
forall a. a -> a
Prelude.id
. :: (b -> c) -> (a -> b) -> a -> c
(.) = (b -> c) -> (a -> b) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
(Prelude..)
instance Category Hask.Op where
id :: Op a a
id = Op a a
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
Hask.id
. :: Op b c -> Op a b -> Op a c
(.) = Op b c -> Op a b -> Op a c
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
(Hask..)
type Hask = Unconstrained⊢(->)
inCategoryOf :: (Category k) => k a b -> k c d -> k a b
k a b
m inCategoryOf :: k a b -> k c d -> k a b
`inCategoryOf` k c d
_ = k a b
m
newtype ConstrainedCategory (k :: * -> * -> *) (o :: * -> Constraint) (a :: *) (b :: *)
= ConstrainedMorphism { ConstrainedCategory k o a b -> k a b
unconstrainedMorphism :: k a b }
type o ⊢ k = ConstrainedCategory k o
constrained :: ∀ o k a b . (Category k, o a, o b) => k a b -> (o⊢k) a b
constrained :: k a b -> (⊢) o k a b
constrained = k a b -> (⊢) o k a b
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism
unconstrained :: ∀ o k a b . (Category k) => (o⊢k) a b -> k a b
unconstrained :: (⊢) o k a b -> k a b
unconstrained = (⊢) o k a b -> k a b
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
ConstrainedCategory k o a b -> k a b
unconstrainedMorphism
instance (Category k) => Category (isObj⊢k) where
type Object (isObj⊢k) o = (Object k o, isObj o)
id :: (⊢) isObj k a a
id = k a a -> (⊢) isObj k a a
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism k a a
forall κ (k :: κ -> κ -> *) (a :: κ).
(Category k, Object k a) =>
k a a
id
ConstrainedMorphism k b c
f . :: (⊢) isObj k b c -> (⊢) isObj k a b -> (⊢) isObj k a c
. ConstrainedMorphism k a b
g = k a c -> (⊢) isObj k a c
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism (k a c -> (⊢) isObj k a c) -> k a c -> (⊢) isObj k a c
forall a b. (a -> b) -> a -> b
$ k b c
f k b c -> k a b -> k a c
forall κ (k :: κ -> κ -> *) (a :: κ) (b :: κ) (c :: κ).
(Category k, Object k a, Object k b, Object k c) =>
k b c -> k a b -> k a c
. k a b
g
type ConstrainedFunction isObj = ConstrainedCategory (->) isObj
{-# DEPRECATED iso "This generic method, while looking nicely uniform, relies on OverlappingInstances and is therefore probably a bad idea. Use the specialised methods in classes like 'SPDistribute' instead." #-}
class (Category k) => Isomorphic k a b where
iso :: k a b
instance (Cartesian k, Object k a, u ~ UnitObject k, ObjectPair k a u) => Isomorphic k a (a,u) where
iso :: k a (a, u)
iso = k a (a, u)
forall (k :: * -> * -> *) unit a.
(Cartesian k, unit ~ UnitObject k, ObjectPair k a unit) =>
k a (a, unit)
attachUnit
instance (Cartesian k, Object k a, u ~ UnitObject k, ObjectPair k a u) => Isomorphic k (a,u) a where
iso :: k (a, u) a
iso = k (a, u) a
forall (k :: * -> * -> *) unit a.
(Cartesian k, unit ~ UnitObject k, ObjectPair k a unit) =>
k (a, unit) a
detachUnit
instance (Cartesian k, Object k a, u ~ UnitObject k, ObjectPair k a u, ObjectPair k u a, Object k (u, a), Object k (a, u) )
=> Isomorphic k a (u,a) where
iso :: k a (u, a)
iso = k (a, u) (u, a)
forall (k :: * -> * -> *) a b.
(Cartesian k, ObjectPair k a b, ObjectPair k b a) =>
k (a, b) (b, a)
swap k (a, u) (u, a) -> k a (a, u) -> k a (u, a)
forall κ (k :: κ -> κ -> *) (a :: κ) (b :: κ) (c :: κ).
(Category k, Object k a, Object k b, Object k c) =>
k b c -> k a b -> k a c
. k a (a, u)
forall (k :: * -> * -> *) unit a.
(Cartesian k, unit ~ UnitObject k, ObjectPair k a unit) =>
k a (a, unit)
attachUnit
instance (Cartesian k, Object k a, u ~ UnitObject k, ObjectPair k a u, ObjectPair k u a, Object k (u, a), Object k (a, u) )
=> Isomorphic k (u,a) a where
iso :: k (u, a) a
iso = k (a, u) a
forall (k :: * -> * -> *) unit a.
(Cartesian k, unit ~ UnitObject k, ObjectPair k a unit) =>
k (a, unit) a
detachUnit k (a, u) a -> k (u, a) (a, u) -> k (u, a) a
forall κ (k :: κ -> κ -> *) (a :: κ) (b :: κ) (c :: κ).
(Category k, Object k a, Object k b, Object k c) =>
k b c -> k a b -> k a c
. k (u, a) (a, u)
forall (k :: * -> * -> *) a b.
(Cartesian k, ObjectPair k a b, ObjectPair k b a) =>
k (a, b) (b, a)
swap
instance ( Cartesian k, Object k a, ObjectPair k a b, ObjectPair k b c
, ObjectPair k a (b,c), ObjectPair k (a,b) c, Object k c )
=> Isomorphic k (a,(b,c)) ((a,b),c) where
iso :: k (a, (b, c)) ((a, b), c)
iso = k (a, (b, c)) ((a, b), c)
forall (k :: * -> * -> *) a b c.
(Cartesian k, ObjectPair k a b, ObjectPair k b c,
ObjectPair k a (b, c), ObjectPair k (a, b) c) =>
k (a, (b, c)) ((a, b), c)
regroup
instance ( Cartesian k, Object k a, ObjectPair k a b, ObjectPair k b c
, ObjectPair k a (b,c), ObjectPair k (a,b) c, Object k c )
=> Isomorphic k ((a,b),c) (a,(b,c)) where
iso :: k ((a, b), c) (a, (b, c))
iso = k ((a, b), c) (a, (b, c))
forall (k :: * -> * -> *) a b c.
(Cartesian k, ObjectPair k a b, ObjectPair k b c,
ObjectPair k a (b, c), ObjectPair k (a, b) c) =>
k ((a, b), c) (a, (b, c))
regroup'
instance (CoCartesian k, Object k a, u ~ ZeroObject k, ObjectSum k a u) => Isomorphic k a (a+u) where
iso :: k a (a + u)
iso = k a (a + u)
forall (k :: * -> * -> *) a zero.
(CoCartesian k, Object k a, zero ~ ZeroObject k,
ObjectSum k a zero) =>
k a (a + zero)
attachZero
instance (CoCartesian k, Object k a, u ~ ZeroObject k, ObjectSum k a u) => Isomorphic k (a+u) a where
iso :: k (a + u) a
iso = k (a + u) a
forall (k :: * -> * -> *) a zero.
(CoCartesian k, Object k a, zero ~ ZeroObject k,
ObjectSum k a zero) =>
k (a + zero) a
detachZero
instance (CoCartesian k, Object k a, u ~ ZeroObject k, ObjectSum k a u, ObjectSum k u a, Object k (u+a), Object k (a+u) )
=> Isomorphic k a (u+a) where
iso :: k a (u + a)
iso = k (a + u) (u + a)
forall (k :: * -> * -> *) a b.
(CoCartesian k, ObjectSum k a b, ObjectSum k b a) =>
k (a + b) (b + a)
coSwap k (a + u) (u + a) -> k a (a + u) -> k a (u + a)
forall κ (k :: κ -> κ -> *) (a :: κ) (b :: κ) (c :: κ).
(Category k, Object k a, Object k b, Object k c) =>
k b c -> k a b -> k a c
. k a (a + u)
forall (k :: * -> * -> *) a zero.
(CoCartesian k, Object k a, zero ~ ZeroObject k,
ObjectSum k a zero) =>
k a (a + zero)
attachZero
instance (CoCartesian k, Object k a, u ~ ZeroObject k, ObjectSum k a u, ObjectSum k u a, Object k (u+a), Object k (a+u) )
=> Isomorphic k (u+a) a where
iso :: k (u + a) a
iso = k (a + u) a
forall (k :: * -> * -> *) a zero.
(CoCartesian k, Object k a, zero ~ ZeroObject k,
ObjectSum k a zero) =>
k (a + zero) a
detachZero k (a + u) a -> k (u + a) (a + u) -> k (u + a) a
forall κ (k :: κ -> κ -> *) (a :: κ) (b :: κ) (c :: κ).
(Category k, Object k a, Object k b, Object k c) =>
k b c -> k a b -> k a c
. k (u + a) (a + u)
forall (k :: * -> * -> *) a b.
(CoCartesian k, ObjectSum k a b, ObjectSum k b a) =>
k (a + b) (b + a)
coSwap
instance ( CoCartesian k, Object k a, ObjectSum k a b, ObjectSum k b c
, ObjectSum k a (b+c), ObjectSum k (a+b) c, Object k c )
=> Isomorphic k (a+(b+c)) ((a+b)+c) where
iso :: k (a + (b + c)) ((a + b) + c)
iso = k (a + (b + c)) ((a + b) + c)
forall (k :: * -> * -> *) a c b.
(CoCartesian k, Object k a, Object k c, ObjectSum k a b,
ObjectSum k b c, ObjectSum k a (b + c), ObjectSum k (a + b) c) =>
k (a + (b + c)) ((a + b) + c)
coRegroup
instance ( CoCartesian k, Object k a, ObjectSum k a b, ObjectSum k b c
, ObjectSum k a (b+c), ObjectSum k (a+b) c, Object k c )
=> Isomorphic k ((a+b)+c) (a+(b+c)) where
iso :: k ((a + b) + c) (a + (b + c))
iso = k ((a + b) + c) (a + (b + c))
forall (k :: * -> * -> *) a c b.
(CoCartesian k, Object k a, Object k c, ObjectSum k a b,
ObjectSum k b c, ObjectSum k a (b + c), ObjectSum k (a + b) c) =>
k ((a + b) + c) (a + (b + c))
coRegroup'
class ( Category k
, Monoid (UnitObject k), Object k (UnitObject k)
) => Cartesian k where
type PairObjects k a b :: Constraint
type PairObjects k a b = ()
type UnitObject k :: *
type UnitObject k = ()
swap :: ( ObjectPair k a b, ObjectPair k b a ) => k (a,b) (b,a)
attachUnit :: ( unit ~ UnitObject k, ObjectPair k a unit ) => k a (a,unit)
detachUnit :: ( unit ~ UnitObject k, ObjectPair k a unit ) => k (a,unit) a
regroup :: ( ObjectPair k a b, ObjectPair k b c
, ObjectPair k a (b,c), ObjectPair k (a,b) c
) => k (a, (b, c)) ((a, b), c)
regroup' :: ( ObjectPair k a b, ObjectPair k b c
, ObjectPair k a (b,c), ObjectPair k (a,b) c
) => k ((a, b), c) (a, (b, c))
type ObjectPair k a b = ( Category k, Object k a, Object k b
, PairObjects k a b, Object k (a,b) )
instance Cartesian (->) where
swap :: (a, b) -> (b, a)
swap = \(a
a,b
b) -> (b
b,a
a)
attachUnit :: a -> (a, unit)
attachUnit = \a
a -> (a
a, ())
detachUnit :: (a, unit) -> a
detachUnit = \(a
a, ()) -> a
a
regroup :: (a, (b, c)) -> ((a, b), c)
regroup = \(a
a, (b
b, c
c)) -> ((a
a, b
b), c
c)
regroup' :: ((a, b), c) -> (a, (b, c))
regroup' = \((a
a, b
b), c
c) -> (a
a, (b
b, c
c))
instance Cartesian Hask.Op where
swap :: Op (a, b) (b, a)
swap = ((b, a) -> (a, b)) -> Op (a, b) (b, a)
forall a b. (b -> a) -> Op a b
Hask.Op (((b, a) -> (a, b)) -> Op (a, b) (b, a))
-> ((b, a) -> (a, b)) -> Op (a, b) (b, a)
forall a b. (a -> b) -> a -> b
$ \(b
a,a
b) -> (a
b,b
a)
attachUnit :: Op a (a, unit)
attachUnit = ((a, ()) -> a) -> Op a (a, ())
forall a b. (b -> a) -> Op a b
Hask.Op (((a, ()) -> a) -> Op a (a, ())) -> ((a, ()) -> a) -> Op a (a, ())
forall a b. (a -> b) -> a -> b
$ \(a
a, ()) -> a
a
detachUnit :: Op (a, unit) a
detachUnit = (a -> (a, ())) -> Op (a, ()) a
forall a b. (b -> a) -> Op a b
Hask.Op ((a -> (a, ())) -> Op (a, ()) a) -> (a -> (a, ())) -> Op (a, ()) a
forall a b. (a -> b) -> a -> b
$ \a
a -> (a
a, ())
regroup :: Op (a, (b, c)) ((a, b), c)
regroup = (((a, b), c) -> (a, (b, c))) -> Op (a, (b, c)) ((a, b), c)
forall a b. (b -> a) -> Op a b
Hask.Op ((((a, b), c) -> (a, (b, c))) -> Op (a, (b, c)) ((a, b), c))
-> (((a, b), c) -> (a, (b, c))) -> Op (a, (b, c)) ((a, b), c)
forall a b. (a -> b) -> a -> b
$ \((a
a, b
b), c
c) -> (a
a, (b
b, c
c))
regroup' :: Op ((a, b), c) (a, (b, c))
regroup' = ((a, (b, c)) -> ((a, b), c)) -> Op ((a, b), c) (a, (b, c))
forall a b. (b -> a) -> Op a b
Hask.Op (((a, (b, c)) -> ((a, b), c)) -> Op ((a, b), c) (a, (b, c)))
-> ((a, (b, c)) -> ((a, b), c)) -> Op ((a, b), c) (a, (b, c))
forall a b. (a -> b) -> a -> b
$ \(a
a, (b
b, c
c)) -> ((a
a, b
b), c
c)
instance (Cartesian f, o (UnitObject f)) => Cartesian (o⊢f) where
type PairObjects (o⊢f) a b = (PairObjects f a b)
type UnitObject (o⊢f) = UnitObject f
swap :: (⊢) o f (a, b) (b, a)
swap = f (a, b) (b, a) -> (⊢) o f (a, b) (b, a)
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f (a, b) (b, a)
forall (k :: * -> * -> *) a b.
(Cartesian k, ObjectPair k a b, ObjectPair k b a) =>
k (a, b) (b, a)
swap
attachUnit :: (⊢) o f a (a, unit)
attachUnit = f a (a, unit) -> (⊢) o f a (a, unit)
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f a (a, unit)
forall (k :: * -> * -> *) unit a.
(Cartesian k, unit ~ UnitObject k, ObjectPair k a unit) =>
k a (a, unit)
attachUnit
detachUnit :: (⊢) o f (a, unit) a
detachUnit = f (a, unit) a -> (⊢) o f (a, unit) a
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f (a, unit) a
forall (k :: * -> * -> *) unit a.
(Cartesian k, unit ~ UnitObject k, ObjectPair k a unit) =>
k (a, unit) a
detachUnit
regroup :: (⊢) o f (a, (b, c)) ((a, b), c)
regroup = f (a, (b, c)) ((a, b), c) -> (⊢) o f (a, (b, c)) ((a, b), c)
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f (a, (b, c)) ((a, b), c)
forall (k :: * -> * -> *) a b c.
(Cartesian k, ObjectPair k a b, ObjectPair k b c,
ObjectPair k a (b, c), ObjectPair k (a, b) c) =>
k (a, (b, c)) ((a, b), c)
regroup
regroup' :: (⊢) o f ((a, b), c) (a, (b, c))
regroup' = f ((a, b), c) (a, (b, c)) -> (⊢) o f ((a, b), c) (a, (b, c))
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f ((a, b), c) (a, (b, c))
forall (k :: * -> * -> *) a b c.
(Cartesian k, ObjectPair k a b, ObjectPair k b c,
ObjectPair k a (b, c), ObjectPair k (a, b) c) =>
k ((a, b), c) (a, (b, c))
regroup'
type (+) = Either
class ( Category k, Object k (ZeroObject k)
) => CoCartesian k where
type SumObjects k a b :: Constraint
type SumObjects k a b = ()
type ZeroObject k :: *
type ZeroObject k = Void
coSwap :: ( ObjectSum k a b, ObjectSum k b a ) => k (a+b) (b+a)
attachZero :: ( Object k a, zero ~ ZeroObject k, ObjectSum k a zero ) => k a (a+zero)
detachZero :: ( Object k a, zero ~ ZeroObject k, ObjectSum k a zero ) => k (a+zero) a
coRegroup :: ( Object k a, Object k c, ObjectSum k a b, ObjectSum k b c
, ObjectSum k a (b+c), ObjectSum k (a+b) c
) => k (a+(b+c)) ((a+b)+c)
coRegroup' :: ( Object k a, Object k c, ObjectSum k a b, ObjectSum k b c
, ObjectSum k a (b+c), ObjectSum k (a+b) c
) => k ((a+b)+c) (a+(b+c))
maybeAsSum :: ( ObjectSum k u a, u ~ UnitObject k, Object k (Maybe a) )
=> k (Maybe a) (u + a)
maybeFromSum :: ( ObjectSum k u a, u ~ UnitObject k, Object k (Maybe a) )
=> k (u + a) (Maybe a)
boolAsSum :: ( ObjectSum k u u, u ~ UnitObject k, Object k Bool )
=> k Bool (u + u)
boolFromSum :: ( ObjectSum k u u, u ~ UnitObject k, Object k Bool )
=> k (u + u) Bool
type ObjectSum k a b = ( Category k, Object k a, Object k b
, SumObjects k a b, Object k (a+b) )
instance CoCartesian (->) where
coSwap :: (a + b) -> b + a
coSwap (Left a
a) = a -> b + a
forall a b. b -> Either a b
Right a
a
coSwap (Right b
a) = b -> b + a
forall a b. a -> Either a b
Left b
a
attachZero :: a -> a + zero
attachZero = a -> a + zero
forall a b. a -> Either a b
Left
detachZero :: (a + zero) -> a
detachZero (Left a
a) = a
a
detachZero (Right zero
void) = Void -> a
forall a. Void -> a
absurd zero
Void
void
coRegroup :: (a + (b + c)) -> (a + b) + c
coRegroup (Left a
a) = (a + b) -> (a + b) + c
forall a b. a -> Either a b
Left ((a + b) -> (a + b) + c) -> (a + b) -> (a + b) + c
forall a b. (a -> b) -> a -> b
$ a -> a + b
forall a b. a -> Either a b
Left a
a
coRegroup (Right (Left b
a)) = (a + b) -> (a + b) + c
forall a b. a -> Either a b
Left ((a + b) -> (a + b) + c) -> (a + b) -> (a + b) + c
forall a b. (a -> b) -> a -> b
$ b -> a + b
forall a b. b -> Either a b
Right b
a
coRegroup (Right (Right c
a)) = c -> (a + b) + c
forall a b. b -> Either a b
Right c
a
coRegroup' :: ((a + b) + c) -> a + (b + c)
coRegroup' (Left (Left a
a)) = a -> a + (b + c)
forall a b. a -> Either a b
Left a
a
coRegroup' (Left (Right b
a)) = (b + c) -> a + (b + c)
forall a b. b -> Either a b
Right ((b + c) -> a + (b + c)) -> (b + c) -> a + (b + c)
forall a b. (a -> b) -> a -> b
$ b -> b + c
forall a b. a -> Either a b
Left b
a
coRegroup' (Right c
a) = (b + c) -> a + (b + c)
forall a b. b -> Either a b
Right ((b + c) -> a + (b + c)) -> (b + c) -> a + (b + c)
forall a b. (a -> b) -> a -> b
$ c -> b + c
forall a b. b -> Either a b
Right c
a
maybeAsSum :: Maybe a -> u + a
maybeAsSum Maybe a
Nothing = () -> Either () a
forall a b. a -> Either a b
Left ()
maybeAsSum (Just a
x) = a -> u + a
forall a b. b -> Either a b
Right a
x
maybeFromSum :: (u + a) -> Maybe a
maybeFromSum (Left ()) = Maybe a
forall a. Maybe a
Nothing
maybeFromSum (Right a
x) = a -> Maybe a
forall a. a -> Maybe a
Just a
x
boolAsSum :: Bool -> u + u
boolAsSum Bool
False = () -> Either () u
forall a b. a -> Either a b
Left ()
boolAsSum Bool
True = () -> Either u ()
forall a b. b -> Either a b
Right ()
boolFromSum :: (u + u) -> Bool
boolFromSum (Left ()) = Bool
False
boolFromSum (Right ()) = Bool
True
instance CoCartesian Hask.Op where
coSwap :: Op (a + b) (b + a)
coSwap = ((b + a) -> a + b) -> Op (a + b) (b + a)
forall a b. (b -> a) -> Op a b
Hask.Op (((b + a) -> a + b) -> Op (a + b) (b + a))
-> ((b + a) -> a + b) -> Op (a + b) (b + a)
forall a b. (a -> b) -> a -> b
$ \case Right a
a -> a -> a + b
forall a b. a -> Either a b
Left a
a
Left b
a -> b -> a + b
forall a b. b -> Either a b
Right b
a
attachZero :: Op a (a + zero)
attachZero = (Either a Void -> a) -> Op a (Either a Void)
forall a b. (b -> a) -> Op a b
Hask.Op ((Either a Void -> a) -> Op a (Either a Void))
-> (Either a Void -> a) -> Op a (Either a Void)
forall a b. (a -> b) -> a -> b
$ \case Left a
a -> a
a
Right Void
void -> Void -> a
forall a. Void -> a
absurd Void
void
detachZero :: Op (a + zero) a
detachZero = (a -> a + zero) -> Op (a + zero) a
forall a b. (b -> a) -> Op a b
Hask.Op a -> a + zero
forall a b. a -> Either a b
Left
coRegroup :: Op (a + (b + c)) ((a + b) + c)
coRegroup = (((a + b) + c) -> a + (b + c)) -> Op (a + (b + c)) ((a + b) + c)
forall a b. (b -> a) -> Op a b
Hask.Op ((((a + b) + c) -> a + (b + c)) -> Op (a + (b + c)) ((a + b) + c))
-> (((a + b) + c) -> a + (b + c)) -> Op (a + (b + c)) ((a + b) + c)
forall a b. (a -> b) -> a -> b
$ \case Left (Left a
a) -> a -> a + (b + c)
forall a b. a -> Either a b
Left a
a
Left (Right b
a) -> ((b + c) -> a + (b + c)
forall a b. b -> Either a b
Right (b -> b + c
forall a b. a -> Either a b
Left b
a))
Right c
a -> (b + c) -> a + (b + c)
forall a b. b -> Either a b
Right (c -> b + c
forall a b. b -> Either a b
Right c
a)
coRegroup' :: Op ((a + b) + c) (a + (b + c))
coRegroup' = ((a + (b + c)) -> (a + b) + c) -> Op ((a + b) + c) (a + (b + c))
forall a b. (b -> a) -> Op a b
Hask.Op (((a + (b + c)) -> (a + b) + c) -> Op ((a + b) + c) (a + (b + c)))
-> ((a + (b + c)) -> (a + b) + c) -> Op ((a + b) + c) (a + (b + c))
forall a b. (a -> b) -> a -> b
$ \case (Left a
a) -> (a + b) -> (a + b) + c
forall a b. a -> Either a b
Left (a -> a + b
forall a b. a -> Either a b
Left a
a)
Right (Left b
a) -> (a + b) -> (a + b) + c
forall a b. a -> Either a b
Left (b -> a + b
forall a b. b -> Either a b
Right b
a)
Right (Right c
a) -> c -> (a + b) + c
forall a b. b -> Either a b
Right c
a
maybeFromSum :: Op (u + a) (Maybe a)
maybeFromSum = (Maybe a -> Either () a) -> Op (Either () a) (Maybe a)
forall a b. (b -> a) -> Op a b
Hask.Op ((Maybe a -> Either () a) -> Op (Either () a) (Maybe a))
-> (Maybe a -> Either () a) -> Op (Either () a) (Maybe a)
forall a b. (a -> b) -> a -> b
$ \case Maybe a
Nothing -> () -> Either () a
forall a b. a -> Either a b
Left ()
Just a
x -> a -> Either () a
forall a b. b -> Either a b
Right a
x
maybeAsSum :: Op (Maybe a) (u + a)
maybeAsSum = (Either () a -> Maybe a) -> Op (Maybe a) (Either () a)
forall a b. (b -> a) -> Op a b
Hask.Op ((Either () a -> Maybe a) -> Op (Maybe a) (Either () a))
-> (Either () a -> Maybe a) -> Op (Maybe a) (Either () a)
forall a b. (a -> b) -> a -> b
$ \case Left () -> Maybe a
forall a. Maybe a
Nothing
Right a
x -> a -> Maybe a
forall a. a -> Maybe a
Just a
x
boolFromSum :: Op (u + u) Bool
boolFromSum = (Bool -> Either () ()) -> Op (Either () ()) Bool
forall a b. (b -> a) -> Op a b
Hask.Op ((Bool -> Either () ()) -> Op (Either () ()) Bool)
-> (Bool -> Either () ()) -> Op (Either () ()) Bool
forall a b. (a -> b) -> a -> b
$ \case Bool
False -> () -> Either () ()
forall a b. a -> Either a b
Left ()
Bool
True -> () -> Either () ()
forall a b. b -> Either a b
Right ()
boolAsSum :: Op Bool (u + u)
boolAsSum = (Either () () -> Bool) -> Op Bool (Either () ())
forall a b. (b -> a) -> Op a b
Hask.Op ((Either () () -> Bool) -> Op Bool (Either () ()))
-> (Either () () -> Bool) -> Op Bool (Either () ())
forall a b. (a -> b) -> a -> b
$ \case Left () -> Bool
False
Right () -> Bool
True
instance (CoCartesian f, o (ZeroObject f)) => CoCartesian (o⊢f) where
type SumObjects (o⊢f) a b = (SumObjects f a b)
type ZeroObject (o⊢f) = ZeroObject f
coSwap :: (⊢) o f (a + b) (b + a)
coSwap = f (a + b) (b + a) -> (⊢) o f (a + b) (b + a)
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f (a + b) (b + a)
forall (k :: * -> * -> *) a b.
(CoCartesian k, ObjectSum k a b, ObjectSum k b a) =>
k (a + b) (b + a)
coSwap
attachZero :: (⊢) o f a (a + zero)
attachZero = f a (a + zero) -> (⊢) o f a (a + zero)
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f a (a + zero)
forall (k :: * -> * -> *) a zero.
(CoCartesian k, Object k a, zero ~ ZeroObject k,
ObjectSum k a zero) =>
k a (a + zero)
attachZero
detachZero :: (⊢) o f (a + zero) a
detachZero = f (a + zero) a -> (⊢) o f (a + zero) a
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f (a + zero) a
forall (k :: * -> * -> *) a zero.
(CoCartesian k, Object k a, zero ~ ZeroObject k,
ObjectSum k a zero) =>
k (a + zero) a
detachZero
coRegroup :: (⊢) o f (a + (b + c)) ((a + b) + c)
coRegroup = f (a + (b + c)) ((a + b) + c)
-> (⊢) o f (a + (b + c)) ((a + b) + c)
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f (a + (b + c)) ((a + b) + c)
forall (k :: * -> * -> *) a c b.
(CoCartesian k, Object k a, Object k c, ObjectSum k a b,
ObjectSum k b c, ObjectSum k a (b + c), ObjectSum k (a + b) c) =>
k (a + (b + c)) ((a + b) + c)
coRegroup
coRegroup' :: (⊢) o f ((a + b) + c) (a + (b + c))
coRegroup' = f ((a + b) + c) (a + (b + c))
-> (⊢) o f ((a + b) + c) (a + (b + c))
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f ((a + b) + c) (a + (b + c))
forall (k :: * -> * -> *) a c b.
(CoCartesian k, Object k a, Object k c, ObjectSum k a b,
ObjectSum k b c, ObjectSum k a (b + c), ObjectSum k (a + b) c) =>
k ((a + b) + c) (a + (b + c))
coRegroup'
maybeAsSum :: (⊢) o f (Maybe a) (u + a)
maybeAsSum = f (Maybe a) (u + a) -> (⊢) o f (Maybe a) (u + a)
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f (Maybe a) (u + a)
forall (k :: * -> * -> *) u a.
(CoCartesian k, ObjectSum k u a, u ~ UnitObject k,
Object k (Maybe a)) =>
k (Maybe a) (u + a)
maybeAsSum
maybeFromSum :: (⊢) o f (u + a) (Maybe a)
maybeFromSum = f (u + a) (Maybe a) -> (⊢) o f (u + a) (Maybe a)
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f (u + a) (Maybe a)
forall (k :: * -> * -> *) u a.
(CoCartesian k, ObjectSum k u a, u ~ UnitObject k,
Object k (Maybe a)) =>
k (u + a) (Maybe a)
maybeFromSum
boolAsSum :: (⊢) o f Bool (u + u)
boolAsSum = f Bool (u + u) -> (⊢) o f Bool (u + u)
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f Bool (u + u)
forall (k :: * -> * -> *) u.
(CoCartesian k, ObjectSum k u u, u ~ UnitObject k,
Object k Bool) =>
k Bool (u + u)
boolAsSum
boolFromSum :: (⊢) o f (u + u) Bool
boolFromSum = f (u + u) Bool -> (⊢) o f (u + u) Bool
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism f (u + u) Bool
forall (k :: * -> * -> *) u.
(CoCartesian k, ObjectSum k u u, u ~ UnitObject k,
Object k Bool) =>
k (u + u) Bool
boolFromSum
type CatTagged k x = Tagged (k (UnitObject k) (UnitObject k)) x
class (Cartesian k) => Curry k where
type MorphObjects k b c :: Constraint
type MorphObjects k b c = ()
uncurry :: (ObjectPair k a b, ObjectMorphism k b c)
=> k a (k b c) -> k (a, b) c
curry :: (ObjectPair k a b, ObjectMorphism k b c)
=> k (a, b) c -> k a (k b c)
apply :: (ObjectMorphism k a b, ObjectPair k (k a b) a)
=> k (k a b, a) b
apply = k (k a b) (k a b) -> k (k a b, a) b
forall (k :: * -> * -> *) a b c.
(Curry k, ObjectPair k a b, ObjectMorphism k b c) =>
k a (k b c) -> k (a, b) c
uncurry k (k a b) (k a b)
forall κ (k :: κ -> κ -> *) (a :: κ).
(Category k, Object k a) =>
k a a
id
type ObjectMorphism k b c = (Object k b, Object k c, MorphObjects k b c, Object k (k b c))
instance Curry (->) where
uncurry :: (a -> b -> c) -> (a, b) -> c
uncurry = (a -> b -> c) -> (a, b) -> c
forall a b c. (a -> b -> c) -> (a, b) -> c
Prelude.uncurry
curry :: ((a, b) -> c) -> a -> b -> c
curry = ((a, b) -> c) -> a -> b -> c
forall a b c. ((a, b) -> c) -> a -> b -> c
Prelude.curry
apply :: (a -> b, a) -> b
apply (a -> b
f,a
x) = a -> b
f a
x
instance (Curry f, o (UnitObject f)) => Curry (o⊢f) where
type MorphObjects (o⊢f) a c = ( MorphObjects f a c, f ~ (->) )
uncurry :: (⊢) o f a ((⊢) o f b c) -> (⊢) o f (a, b) c
uncurry (ConstrainedMorphism f a ((⊢) o f b c)
f) = f (a, b) c -> (⊢) o f (a, b) c
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism (f (a, b) c -> (⊢) o f (a, b) c) -> f (a, b) c -> (⊢) o f (a, b) c
forall a b. (a -> b) -> a -> b
$ \(a
a,b
b) -> (⊢) o (->) b c -> b -> c
forall (o :: * -> Constraint) (k :: * -> * -> *) a b.
Category k =>
(⊢) o k a b -> k a b
unconstrained (f a ((⊢) o f b c)
a -> (⊢) o (->) b c
f a
a) b
b
curry :: (⊢) o f (a, b) c -> (⊢) o f a ((⊢) o f b c)
curry (ConstrainedMorphism f (a, b) c
f) = f a ((⊢) o f b c) -> (⊢) o f a ((⊢) o f b c)
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism (f a ((⊢) o f b c) -> (⊢) o f a ((⊢) o f b c))
-> f a ((⊢) o f b c) -> (⊢) o f a ((⊢) o f b c)
forall a b. (a -> b) -> a -> b
$ \a
a -> (b -> c) -> ConstrainedCategory (->) o b c
forall (k :: * -> * -> *) (o :: * -> Constraint) a b.
k a b -> ConstrainedCategory k o a b
ConstrainedMorphism ((b -> c) -> ConstrainedCategory (->) o b c)
-> (b -> c) -> ConstrainedCategory (->) o b c
forall a b. (a -> b) -> a -> b
$ \b
b -> f (a, b) c
(a, b) -> c
f (a
a, b
b)
infixr 0 $~
class (Category k) => HasAgent k where
type AgentVal k a v :: *
type AgentVal k a v = GenericAgent k a v
alg :: ( Object k a, Object k b
) => (forall q . Object k q
=> AgentVal k q a -> AgentVal k q b) -> k a b
($~) :: ( Object k a, Object k b, Object k c
) => k b c -> AgentVal k a b -> AgentVal k a c
data GenericAgent k a v = GenericAgent { GenericAgent k a v -> k a v
runGenericAgent :: k a v }
genericAlg :: ( HasAgent k, Object k a, Object k b )
=> ( forall q . Object k q
=> GenericAgent k q a -> GenericAgent k q b ) -> k a b
genericAlg :: (forall q. Object k q => GenericAgent k q a -> GenericAgent k q b)
-> k a b
genericAlg forall q. Object k q => GenericAgent k q a -> GenericAgent k q b
f = GenericAgent k a b -> k a b
forall k k (k :: k -> k -> *) (a :: k) (v :: k).
GenericAgent k a v -> k a v
runGenericAgent (GenericAgent k a b -> k a b)
-> (GenericAgent k a a -> GenericAgent k a b)
-> GenericAgent k a a
-> k a b
forall κ (k :: κ -> κ -> *) (a :: κ) (b :: κ) (c :: κ).
(Category k, Object k a, Object k b, Object k c) =>
k b c -> k a b -> k a c
. GenericAgent k a a -> GenericAgent k a b
forall q. Object k q => GenericAgent k q a -> GenericAgent k q b
f (GenericAgent k a a -> k a b) -> GenericAgent k a a -> k a b
forall a b. (a -> b) -> a -> b
$ k a a -> GenericAgent k a a
forall k k (k :: k -> k -> *) (a :: k) (v :: k).
k a v -> GenericAgent k a v
GenericAgent k a a
forall κ (k :: κ -> κ -> *) (a :: κ).
(Category k, Object k a) =>
k a a
id
genericAgentMap :: ( HasAgent k, Object k a, Object k b, Object k c )
=> k b c -> GenericAgent k a b -> GenericAgent k a c
genericAgentMap :: k b c -> GenericAgent k a b -> GenericAgent k a c
genericAgentMap k b c
m (GenericAgent k a b
v) = k a c -> GenericAgent k a c
forall k k (k :: k -> k -> *) (a :: k) (v :: k).
k a v -> GenericAgent k a v
GenericAgent (k a c -> GenericAgent k a c) -> k a c -> GenericAgent k a c
forall a b. (a -> b) -> a -> b
$ k b c
m k b c -> k a b -> k a c
forall κ (k :: κ -> κ -> *) (a :: κ) (b :: κ) (c :: κ).
(Category k, Object k a, Object k b, Object k c) =>
k b c -> k a b -> k a c
. k a b
v
instance HasAgent (->) where
type AgentVal (->) a b = b
alg :: (forall q. Object (->) q => AgentVal (->) q a -> AgentVal (->) q b)
-> a -> b
alg forall q. Object (->) q => AgentVal (->) q a -> AgentVal (->) q b
f = a -> b
forall q. Object (->) q => AgentVal (->) q a -> AgentVal (->) q b
f
$~ :: (b -> c) -> AgentVal (->) a b -> AgentVal (->) a c
($~) = (b -> c) -> AgentVal (->) a b -> AgentVal (->) a c
forall a b. (a -> b) -> a -> b
($)
instance HasAgent Discrete where
alg :: (forall q.
Object Discrete q =>
AgentVal Discrete q a -> AgentVal Discrete q b)
-> Discrete a b
alg = (forall q.
Object Discrete q =>
AgentVal Discrete q a -> AgentVal Discrete q b)
-> Discrete a b
forall (k :: * -> * -> *) a b.
(HasAgent k, Object k a, Object k b) =>
(forall q. Object k q => GenericAgent k q a -> GenericAgent k q b)
-> k a b
genericAlg
$~ :: Discrete b c -> AgentVal Discrete a b -> AgentVal Discrete a c
($~) = Discrete b c -> AgentVal Discrete a b -> AgentVal Discrete a c
forall (k :: * -> * -> *) a b c.
(HasAgent k, Object k a, Object k b, Object k c) =>
k b c -> GenericAgent k a b -> GenericAgent k a c
genericAgentMap
instance Category Coercion where
id :: Coercion a a
id = Coercion a a
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
Hask.id
. :: Coercion b c -> Coercion a b -> Coercion a c
(.) = Coercion b c -> Coercion a b -> Coercion a c
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
(Hask..)