Redefine bifunctors in terms of product categories.
parent
05ddc84fff
commit
8a1fad57df
|
@ -10,10 +10,11 @@ jobs:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Install latest Haskell Stack
|
- name: Install Haskell toolchain
|
||||||
uses: haskell/actions/setup@v1
|
uses: haskell/actions/setup@v1
|
||||||
with:
|
with:
|
||||||
ghc-version: '9.0.1'
|
ghc-version: '9.0.1'
|
||||||
|
cabal-version: '3.4.0.0'
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cabal v2-build
|
run: cabal v2-build
|
||||||
|
|
|
@ -28,6 +28,7 @@ library
|
||||||
Category.Groupoid
|
Category.Groupoid
|
||||||
Category.Monoid
|
Category.Monoid
|
||||||
Category.Monoidal
|
Category.Monoidal
|
||||||
|
Category.Product
|
||||||
Category.Semigroup
|
Category.Semigroup
|
||||||
Data.Dict
|
Data.Dict
|
||||||
Data.Fin
|
Data.Fin
|
||||||
|
@ -88,6 +89,7 @@ library
|
||||||
TupleSections
|
TupleSections
|
||||||
TypeApplications
|
TypeApplications
|
||||||
TypeFamilyDependencies
|
TypeFamilyDependencies
|
||||||
|
TypeInType
|
||||||
TypeOperators
|
TypeOperators
|
||||||
TypeSynonymInstances
|
TypeSynonymInstances
|
||||||
ViewPatterns
|
ViewPatterns
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
{-# LANGUAGE UndecidableInstances #-}
|
||||||
{-# LANGUAGE UndecidableSuperClasses #-}
|
{-# LANGUAGE UndecidableSuperClasses #-}
|
||||||
module Category.Constraint
|
module Category.Constraint
|
||||||
( (:-) (Sub), (\\)
|
( (:-) (Sub), (\\)
|
||||||
|
@ -7,6 +8,7 @@ module Category.Constraint
|
||||||
import Category.Base
|
import Category.Base
|
||||||
import Category.Functor
|
import Category.Functor
|
||||||
import Category.Monoidal
|
import Category.Monoidal
|
||||||
|
import Category.Product
|
||||||
import Data.Dict
|
import Data.Dict
|
||||||
import Data.Kind (Constraint, Type)
|
import Data.Kind (Constraint, Type)
|
||||||
|
|
||||||
|
@ -23,7 +25,7 @@ instance NiceCat (:-) where
|
||||||
id = Sub Dict
|
id = Sub Dict
|
||||||
|
|
||||||
instance Functor (Nat (->) (:-)) (Yoneda (:-)) (:-) where
|
instance Functor (Nat (->) (:-)) (Yoneda (:-)) (:-) where
|
||||||
map (Op (Sub f)) = Nat \_ (Sub g) -> Sub case f of Dict -> case g of Dict -> Dict
|
map (Op (Sub f)) = Nat_ \(Sub g) -> Sub case f of Dict -> case g of Dict -> Dict
|
||||||
|
|
||||||
instance Functor (->) (:-) ((:-) a) where
|
instance Functor (->) (:-) ((:-) a) where
|
||||||
map = (.)
|
map = (.)
|
||||||
|
@ -31,6 +33,15 @@ instance Functor (->) (:-) ((:-) a) where
|
||||||
instance Functor (->) (:-) Dict where
|
instance Functor (->) (:-) Dict where
|
||||||
map f = \Dict -> case f of Sub Dict -> Dict
|
map f = \Dict -> case f of Sub Dict -> Dict
|
||||||
|
|
||||||
|
type UncurryC :: (a -> b -> Constraint) -> (a, b) -> Constraint
|
||||||
|
class f (Pi1 ab) (Pi2 ab) => UncurryC f ab
|
||||||
|
instance f (Pi1 ab) (Pi2 ab) => UncurryC f ab
|
||||||
|
type instance Uncurry = UncurryC
|
||||||
|
|
||||||
|
instance Unc (:-) where
|
||||||
|
uncurry _ = Sub Dict
|
||||||
|
ununcurry _ = Sub Dict
|
||||||
|
|
||||||
class (c, d) => ProdC c d
|
class (c, d) => ProdC c d
|
||||||
instance (c, d) => ProdC c d
|
instance (c, d) => ProdC c d
|
||||||
-- Note that, to my understanding,
|
-- Note that, to my understanding,
|
||||||
|
|
|
@ -3,8 +3,6 @@ module Category.Functor
|
||||||
( Functor, map
|
( Functor, map
|
||||||
, Endo, Endofunctor, endomap
|
, Endo, Endofunctor, endomap
|
||||||
, Contravariant, contramap
|
, Contravariant, contramap
|
||||||
, Bifunctor, bimap, first, second
|
|
||||||
, Profunctor, dimap, lmap, rmap
|
|
||||||
, Nat (Nat), runNat, pattern Nat_, natId
|
, Nat (Nat), runNat, pattern Nat_, natId
|
||||||
, Const (Const), getConst
|
, Const (Const), getConst
|
||||||
) where
|
) where
|
||||||
|
@ -35,28 +33,6 @@ instance {-# INCOHERENT #-} Functor dest (Yoneda src) f => Contravariant dest sr
|
||||||
instance {-# INCOHERENT #-} Functor dest src f => Contravariant dest (Yoneda src) f where
|
instance {-# INCOHERENT #-} Functor dest src f => Contravariant dest (Yoneda src) f where
|
||||||
contramap (Op f) = map f
|
contramap (Op f) = map f
|
||||||
|
|
||||||
type Bifunctor :: (j -> j -> Type) -> (i -> i -> Type) -> (i -> i -> j) -> Constraint
|
|
||||||
class (Functor (Nat dest src) src f, forall x. Functor dest src (f x)) => Bifunctor dest src f
|
|
||||||
instance (Functor (Nat dest src) src f, forall x. Functor dest src (f x)) => Bifunctor dest src f
|
|
||||||
bimap :: Bifunctor dest src f => src a c -> src b d -> dest (f a b) (f c d)
|
|
||||||
bimap f g = runNat (map f) (idR g) . map g
|
|
||||||
-- FIXME: A NiceCat dependency should not be necessary here,
|
|
||||||
-- this most likely means that my definition of Bifunctor is inadequate.
|
|
||||||
first :: forall dest src f a b c. (Bifunctor dest src f, NiceCat src) => src a b -> dest (f a c) (f b c)
|
|
||||||
first f = runNat (map f) (id :: Obj src c)
|
|
||||||
second :: Bifunctor dest src f => src b c -> dest (f a b) (f a c)
|
|
||||||
second g = map g
|
|
||||||
|
|
||||||
type Profunctor :: (j -> j -> Type) -> (i -> i -> Type) -> (i -> i -> j) -> Constraint
|
|
||||||
class (Functor (Nat dest src) (Yoneda src) f, forall x. Functor dest src (f x)) => Profunctor dest src f
|
|
||||||
instance (Functor (Nat dest src) (Yoneda src) f, forall x. Functor dest src (f x)) => Profunctor dest src f
|
|
||||||
dimap :: Profunctor dest src f => src a b -> src c d -> dest (f b c) (f a d)
|
|
||||||
dimap f g = runNat (map (Op f)) (idR g) . map g
|
|
||||||
lmap :: forall dest src f a b c. (Profunctor dest src f, NiceCat src) => src a b -> dest (f b c) (f a c)
|
|
||||||
lmap f = runNat (map (Op f)) (id :: Obj src c)
|
|
||||||
rmap :: Profunctor dest src f => src b c -> dest (f a b) (f a c)
|
|
||||||
rmap f = map f
|
|
||||||
|
|
||||||
type Nat :: (j -> j -> Type) -> (i -> i -> Type) -> (i -> j) -> (i -> j) -> Type
|
type Nat :: (j -> j -> Type) -> (i -> i -> Type) -> (i -> j) -> (i -> j) -> Type
|
||||||
data Nat dest src f g = (Functor dest src f, Functor dest src g) => Nat { runNat :: !(forall a. Obj src a -> dest (f a) (g a)) }
|
data Nat dest src f g = (Functor dest src f, Functor dest src g) => Nat { runNat :: !(forall a. Obj src a -> dest (f a) (g a)) }
|
||||||
|
|
||||||
|
@ -86,16 +62,16 @@ instance Functor (->) (FUN m) (FUN m a) where
|
||||||
map f = \g -> f . g
|
map f = \g -> f . g
|
||||||
|
|
||||||
instance Functor (Nat (->) (FUN m)) (Yoneda (FUN m)) (FUN m) where
|
instance Functor (Nat (->) (FUN m)) (Yoneda (FUN m)) (FUN m) where
|
||||||
map (Op f) = Nat \_ g -> g . f
|
map (Op f) = Nat_ \g -> g . f
|
||||||
|
|
||||||
instance Functor (Nat (FUN m) (FUN m)) (FUN m) (,) where
|
instance Functor (Nat (FUN m) (FUN m)) (FUN m) (,) where
|
||||||
map f = Nat \_ (x, y) -> (f x, y)
|
map f = Nat_ \(x, y) -> (f x, y)
|
||||||
|
|
||||||
instance Functor (FUN m) (FUN m) ((,) a) where
|
instance Functor (FUN m) (FUN m) ((,) a) where
|
||||||
map f = \(x, y) -> (x, f y)
|
map f = \(x, y) -> (x, f y)
|
||||||
|
|
||||||
instance Functor (Nat (FUN m) (FUN m)) (FUN m) Either where
|
instance Functor (Nat (FUN m) (FUN m)) (FUN m) Either where
|
||||||
map f = Nat \_ -> \case
|
map f = Nat_ \case
|
||||||
Left y -> Left (f y)
|
Left y -> Left (f y)
|
||||||
Right x -> Right x
|
Right x -> Right x
|
||||||
|
|
||||||
|
@ -116,7 +92,7 @@ type Const :: Type -> i -> Type
|
||||||
newtype Const a b = Const { getConst :: a }
|
newtype Const a b = Const { getConst :: a }
|
||||||
|
|
||||||
instance Functor (Nat (->) (->)) (->) Const where
|
instance Functor (Nat (->) (->)) (->) Const where
|
||||||
map f = Nat \_ (Const x) -> Const (f x)
|
map f = Nat_ \(Const x) -> Const (f x)
|
||||||
|
|
||||||
instance {-# INCOHERENT #-} Category src => Functor (->) src (Const a) where
|
instance {-# INCOHERENT #-} Category src => Functor (->) src (Const a) where
|
||||||
map _ = \(Const x) -> Const x
|
map _ = \(Const x) -> Const x
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
module Category.Monoidal
|
module Category.Monoidal
|
||||||
( TensorProduct, Unit, unitObj, prodObj, prodIL, prodIR, prodEL, prodER, prodAL, prodAR
|
( TensorProduct, Unit, unitObj, prodObj, prodIL, prodIR, prodEL, prodER, prodAL, prodAR
|
||||||
|
, prodIL_, prodIR_, prodEL_, prodER_, prodAL_, prodAR_
|
||||||
, Compose (Compose), getCompose
|
, Compose (Compose), getCompose
|
||||||
, Identity (Identity), getIdentity
|
, Identity (Identity), getIdentity
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Category.Base
|
import Category.Base
|
||||||
import Category.Functor
|
import Category.Functor
|
||||||
|
import Category.Product
|
||||||
import Data.Either (Either (Left, Right))
|
import Data.Either (Either (Left, Right))
|
||||||
import Data.Kind (Constraint, FUN, Type)
|
import Data.Kind (Constraint, FUN, Type)
|
||||||
import Data.Void (Void)
|
import Data.Void (Void)
|
||||||
|
@ -15,7 +17,7 @@ import Data.Void (Void)
|
||||||
-- including the category of types itself,
|
-- including the category of types itself,
|
||||||
-- so instead of using a @Monoidal@ typeclass, we use a @TensorProduct@ typeclass.
|
-- so instead of using a @Monoidal@ typeclass, we use a @TensorProduct@ typeclass.
|
||||||
type TensorProduct :: (i -> i -> Type) -> (i -> i -> i) -> Constraint
|
type TensorProduct :: (i -> i -> Type) -> (i -> i -> i) -> Constraint
|
||||||
class Endo Bifunctor morph prod => TensorProduct (morph :: i -> i -> Type) prod where
|
class Bifunctor morph morph morph prod => TensorProduct (morph :: i -> i -> Type) prod where
|
||||||
type Unit morph prod :: i
|
type Unit morph prod :: i
|
||||||
-- | The unit is an object.
|
-- | The unit is an object.
|
||||||
unitObj :: proxy prod -> Obj morph (Unit morph prod)
|
unitObj :: proxy prod -> Obj morph (Unit morph prod)
|
||||||
|
@ -40,6 +42,24 @@ class Endo Bifunctor morph prod => TensorProduct (morph :: i -> i -> Type) prod
|
||||||
-- | Reassociate a product, nesting it to the right.
|
-- | Reassociate a product, nesting it to the right.
|
||||||
prodAR :: Obj morph a -> Obj morph b -> Obj morph c -> morph (prod (prod a b) c) (prod a (prod b c))
|
prodAR :: Obj morph a -> Obj morph b -> Obj morph c -> morph (prod (prod a b) c) (prod a (prod b c))
|
||||||
|
|
||||||
|
prodIL_ :: (NiceCat morph, TensorProduct morph prod) => morph a (prod a (Unit morph prod))
|
||||||
|
prodIL_ = prodIL id
|
||||||
|
|
||||||
|
prodIR_ :: (NiceCat morph, TensorProduct morph prod) => morph a (prod (Unit morph prod) a)
|
||||||
|
prodIR_ = prodIR id
|
||||||
|
|
||||||
|
prodEL_ :: (NiceCat morph, TensorProduct morph prod) => morph (prod a (Unit morph prod)) a
|
||||||
|
prodEL_ = prodEL id
|
||||||
|
|
||||||
|
prodER_ :: (NiceCat morph, TensorProduct morph prod) => morph (prod (Unit morph prod) a) a
|
||||||
|
prodER_ = prodER id
|
||||||
|
|
||||||
|
prodAL_ :: (NiceCat morph, TensorProduct morph prod) => morph (prod a (prod b c)) (prod (prod a b) c)
|
||||||
|
prodAL_ = prodAL id id id
|
||||||
|
|
||||||
|
prodAR_ :: (NiceCat morph, TensorProduct morph prod) => morph (prod (prod a b) c) (prod a (prod b c))
|
||||||
|
prodAR_ = prodAR id id id
|
||||||
|
|
||||||
instance TensorProduct (FUN m) (,) where
|
instance TensorProduct (FUN m) (,) where
|
||||||
type Unit (FUN m) (,) = ()
|
type Unit (FUN m) (,) = ()
|
||||||
prodIL _ = \x -> (x, ())
|
prodIL _ = \x -> (x, ())
|
||||||
|
@ -49,20 +69,27 @@ instance TensorProduct (FUN m) (,) where
|
||||||
prodAL _ _ _ = \(x, (y, z)) -> ((x, y), z)
|
prodAL _ _ _ = \(x, (y, z)) -> ((x, y), z)
|
||||||
prodAR _ _ _ = \((x, y), z) -> (x, (y, z))
|
prodAR _ _ _ = \((x, y), z) -> (x, (y, z))
|
||||||
|
|
||||||
|
absurd :: Void %1-> a
|
||||||
|
absurd = \case{}
|
||||||
|
|
||||||
instance TensorProduct (FUN m) Either where
|
instance TensorProduct (FUN m) Either where
|
||||||
type Unit (FUN m) Either = Void
|
type Unit (FUN m) Either = Void
|
||||||
prodIL _ = Left
|
prodIL _ = Left
|
||||||
prodIR _ = Right
|
prodIR _ = Right
|
||||||
prodEL _ (Left x) = x
|
prodEL _ = \case
|
||||||
prodEL _ (Right x) = (\case{}) x
|
Left x -> x
|
||||||
prodER _ (Left x) = (\case{}) x
|
Right x -> absurd x
|
||||||
prodER _ (Right x) = x
|
prodER _ = \case
|
||||||
prodAL _ _ _ (Left x) = Left (Left x)
|
Left x -> absurd x
|
||||||
prodAL _ _ _ (Right (Left x)) = Left (Right x)
|
Right x -> x
|
||||||
prodAL _ _ _ (Right (Right x)) = Right x
|
prodAL _ _ _ = \case
|
||||||
prodAR _ _ _ (Left (Left x)) = Left x
|
Left x -> Left (Left x)
|
||||||
prodAR _ _ _ (Left (Right x)) = Right (Left x)
|
Right (Left x) -> Left (Right x)
|
||||||
prodAR _ _ _ (Right x) = Right (Right x)
|
Right (Right x) -> Right x
|
||||||
|
prodAR _ _ _ = \case
|
||||||
|
Left (Left x) -> Left x
|
||||||
|
Left (Right x) -> Right (Left x)
|
||||||
|
Right x -> Right (Right x)
|
||||||
|
|
||||||
data Compose f g x = (Functor (->) (->) f, Functor (->) (->) g) => Compose { getCompose :: !(f (g x)) }
|
data Compose f g x = (Functor (->) (->) f, Functor (->) (->) g) => Compose { getCompose :: !(f (g x)) }
|
||||||
newtype Identity x = Identity { getIdentity :: x }
|
newtype Identity x = Identity { getIdentity :: x }
|
||||||
|
@ -71,10 +98,10 @@ instance Functor (FUN m) (FUN m) Identity where
|
||||||
map f = \(Identity x) -> Identity (f x)
|
map f = \(Identity x) -> Identity (f x)
|
||||||
|
|
||||||
instance Functor (Nat (Nat (->) (->)) (Nat (->) (->))) (Nat (->) (->)) Compose where
|
instance Functor (Nat (Nat (->) (->)) (Nat (->) (->))) (Nat (->) (->)) Compose where
|
||||||
map (Nat f) = Nat \(Nat _) -> Nat \_ (Compose x) -> Compose (f id x)
|
map (Nat f) = Nat \(Nat _) -> Nat_ \(Compose x) -> Compose (f id x)
|
||||||
|
|
||||||
instance Functor (Nat (->) (->)) (Nat (->) (->)) (Compose f) where
|
instance Functor (Nat (->) (->)) (Nat (->) (->)) (Compose f) where
|
||||||
map (Nat f) = Nat \_ (Compose x) -> Compose (map (f id) x)
|
map (Nat f) = Nat_ \(Compose x) -> Compose (map (f id) x)
|
||||||
|
|
||||||
instance Functor (->) (->) (Compose (f :: Type -> Type) g) where
|
instance Functor (->) (->) (Compose (f :: Type -> Type) g) where
|
||||||
map f = \(Compose x) -> Compose (map @_ @_ @_ @(->) (map f) x)
|
map f = \(Compose x) -> Compose (map @_ @_ @_ @(->) (map f) x)
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
{-# LANGUAGE UndecidableInstances, UndecidableSuperClasses #-}
|
||||||
|
module Category.Product
|
||||||
|
( Pi1, Pi2, pairEta
|
||||||
|
, Product (Product)
|
||||||
|
, Uncurry, Uncurry' (Uncurry), getUncurry, UncurryN (UncurryN), getUncurryN
|
||||||
|
, Unc, uncurry, ununcurry
|
||||||
|
, Bifunctor, bimap_, bimap, first, second
|
||||||
|
, Profunctor, dimap
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Category.Base
|
||||||
|
import Category.Functor
|
||||||
|
import Data.Dict
|
||||||
|
import Data.Kind (Constraint, FUN, Type)
|
||||||
|
import Data.Proxy
|
||||||
|
import Unsafe.Coerce (unsafeCoerce)
|
||||||
|
|
||||||
|
-- | The first projection of the type-level tuple.
|
||||||
|
type Pi1 :: (i, j) -> i
|
||||||
|
type family Pi1 xy where
|
||||||
|
Pi1 '(x, _) = x
|
||||||
|
|
||||||
|
-- | The second projection of the type-level tuple.
|
||||||
|
type Pi2 :: (i, j) -> j
|
||||||
|
type family Pi2 xy where
|
||||||
|
Pi2 '(_, y) = y
|
||||||
|
|
||||||
|
-- | Eta expansion for the pair type *on the type level*. **This does not hold on the value level.**
|
||||||
|
--
|
||||||
|
-- This is not provable by GHC's constraint solver, but it is safe to assume.
|
||||||
|
-- Maybe. Hopefully.
|
||||||
|
pairEta :: proxy x -> Dict (x ~ '(Pi1 x, Pi2 x))
|
||||||
|
pairEta = unsafeCoerce (Dict :: Dict ())
|
||||||
|
|
||||||
|
-- | The product category of two categories `c` and `d` is the category
|
||||||
|
-- whose objects are pairs of objects from `c` and `d` and whose arrows
|
||||||
|
-- are pairs of arrows from `c` and `d`.
|
||||||
|
type Product :: (i -> i -> Type) -> (j -> j -> Type) -> (i, j) -> (i, j) -> Type
|
||||||
|
data Product c d a b = Product !(c (Pi1 a) (Pi1 b)) !(d (Pi2 a) (Pi2 b))
|
||||||
|
|
||||||
|
instance (Category c, Category d) => Category (Product c d) where
|
||||||
|
idL (Product f g) = Product (idL f) (idL g)
|
||||||
|
idR (Product f g) = Product (idR f) (idR g)
|
||||||
|
Product f1 g1 . Product f2 g2 = Product (f1 . f2) (g1 . g2)
|
||||||
|
|
||||||
|
instance (NiceCat c, NiceCat d) => NiceCat (Product c d) where
|
||||||
|
id = Product id id
|
||||||
|
|
||||||
|
type Uncurry :: (a -> b -> c) -> (a, b) -> c
|
||||||
|
type family Uncurry
|
||||||
|
|
||||||
|
type Uncurry' :: (a -> b -> Type) -> (a, b) -> Type
|
||||||
|
newtype Uncurry' f ab = Uncurry { getUncurry :: f (Pi1 ab) (Pi2 ab) }
|
||||||
|
type instance Uncurry = Uncurry'
|
||||||
|
|
||||||
|
type UncurryN :: (a -> b -> c -> Type) -> (a, b) -> c -> Type
|
||||||
|
newtype UncurryN f ab x = UncurryN { getUncurryN :: f (Pi1 ab) (Pi2 ab) x }
|
||||||
|
type instance Uncurry = UncurryN
|
||||||
|
|
||||||
|
instance (Category c, Functor (->) c (f a b)) => Functor (->) c (UncurryN f '(a, b)) where
|
||||||
|
map f (UncurryN x) = UncurryN (map f x)
|
||||||
|
|
||||||
|
type Unc :: (c -> c -> Type) -> Constraint
|
||||||
|
class Category cat => Unc cat where
|
||||||
|
uncurry :: Obj cat (f a b) -> cat (f a b) (Uncurry f '(a, b))
|
||||||
|
ununcurry :: Obj cat (f a b) -> cat (Uncurry f '(a, b)) (f a b)
|
||||||
|
|
||||||
|
instance Unc (FUN m) where
|
||||||
|
uncurry _ = Uncurry
|
||||||
|
ununcurry _ (Uncurry x) = x
|
||||||
|
|
||||||
|
instance Unc (Nat (->) (->)) where
|
||||||
|
uncurry (Nat _) = Nat_ UncurryN
|
||||||
|
ununcurry (Nat _) = Nat_ \(UncurryN x) -> x
|
||||||
|
|
||||||
|
-- | A bifunctor is a functor whose domain is the product category.
|
||||||
|
type Bifunctor :: (k -> k -> Type) -> (i -> i -> Type) -> (j -> j -> Type) -> (i -> j -> k) -> Constraint
|
||||||
|
class (Unc cod, Category dom1, Category dom2, Functor cod (Product dom1 dom2) (Uncurry f)) => Bifunctor cod dom1 dom2 f where
|
||||||
|
bimap_ :: forall a b. Obj dom1 a -> Obj dom2 b -> Obj cod (f a b)
|
||||||
|
|
||||||
|
bimap :: forall cod dom1 dom2 f a b c d. Bifunctor cod dom1 dom2 f => dom1 a c -> dom2 b d -> cod (f a b) (f c d)
|
||||||
|
bimap f g = ununcurry (bimap_ (idR f) (idR g)) . map (Product f g) . uncurry (bimap_ (idL f) (idL g))
|
||||||
|
|
||||||
|
first :: forall cod dom f a b c. (NiceCat dom, Bifunctor cod dom dom f) => dom a b -> cod (f a c) (f b c)
|
||||||
|
first f = bimap f (id :: dom c c)
|
||||||
|
|
||||||
|
second :: forall cod dom f a b c. (NiceCat dom, Bifunctor cod dom dom f) => dom b c -> cod (f a b) (f a c)
|
||||||
|
second g = bimap (id :: dom a a) g
|
||||||
|
|
||||||
|
instance (Unc cod, Functor (Nat cod dom2) dom1 f, forall x. Functor cod dom2 (f x), uncurry ~ Uncurry) => Functor cod (Product dom1 dom2) (uncurry f) where
|
||||||
|
{-# INLINABLE map #-}
|
||||||
|
map :: forall a b. Product dom1 dom2 a b -> cod (uncurry f a) (uncurry f b)
|
||||||
|
map (Product f g) = lemma (uncurry (map (idR g)) . runNat (map f) (idR g) . map g . ununcurry (map (idL g)))
|
||||||
|
where lemma :: ((a ~ '(Pi1 a, Pi2 a), b ~ '(Pi1 b, Pi2 b)) => c) -> c
|
||||||
|
lemma x = case pairEta (Proxy @a) of Dict -> case pairEta (Proxy @b) of Dict -> x
|
||||||
|
instance (Unc cod, Category dom1, Functor (Nat cod dom2) dom1 f, forall x. Functor cod dom2 (f x)) => Bifunctor cod dom1 dom2 f where
|
||||||
|
bimap_ a b = runNat (map a) b . map b
|
||||||
|
|
||||||
|
type Profunctor :: (k -> k -> Type) -> (i -> i -> Type) -> (j -> j -> Type) -> (i -> j -> k) -> Constraint
|
||||||
|
class Bifunctor cod (Yoneda dom1) dom2 f => Profunctor cod dom1 dom2 f
|
||||||
|
instance Bifunctor cod (Yoneda dom1) dom2 f => Profunctor cod dom1 dom2 f
|
||||||
|
|
||||||
|
dimap :: Profunctor cod dom1 dom2 f => dom1 c a -> dom2 b d -> cod (f a b) (f c d)
|
||||||
|
dimap f g = bimap (Op f) g
|
|
@ -10,7 +10,7 @@ class TensorProduct morph prod => Semigroup morph prod s where
|
||||||
append :: morph (prod s s) s
|
append :: morph (prod s s) s
|
||||||
|
|
||||||
instance Semigroup (Nat (->) (->)) Compose Maybe where
|
instance Semigroup (Nat (->) (->)) Compose Maybe where
|
||||||
append = Nat \_ (Compose x') -> case x' of
|
append = Nat_ \(Compose x') -> case x' of
|
||||||
Nothing -> Nothing
|
Nothing -> Nothing
|
||||||
Just Nothing -> Nothing
|
Just Nothing -> Nothing
|
||||||
Just (Just x) -> Just x
|
Just (Just x) -> Just x
|
||||||
|
|
Loading…
Reference in New Issue