lude

Haskell prelude alternative
git clone git://git.rr3.xyz/lude | git clone gits://git.rr3.xyz/lude
Log | Files | Refs | LICENSE

commit 02d083d8977a8522a1d5909dcacefd027f831af5
parent 1e3c6d28859992b3781cd8f69c261269871a00b6
Author: Robert Russell <robert@rr3.xyz>
Date:   Sun, 15 Mar 2026 14:46:06 -0700

Complete categorical products and sums

Diffstat:
Msrc/Lude/Algebra/Category.hs | 93+++++++++++++++++++++++++++++++------------------------------------------------
1 file changed, 36 insertions(+), 57 deletions(-)

diff --git a/src/Lude/Algebra/Category.hs b/src/Lude/Algebra/Category.hs @@ -1,6 +1,5 @@ {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE UndecidableInstances #-} -{-# LANGUAGE UndecidableSuperClasses #-} module Lude.Algebra.Category ( Cat, @@ -17,24 +16,6 @@ import Lude.Pair -- TODO: Allow non-BoxL morphism Repr? -- TODO: Filterable is functor from Kleisli Option to Hask --- type Type2 i = i -> i -> Type --- type Constraint2 i = i -> i -> Constraint - --- type Pair2 :: forall i j. Type2 i -> Type2 j -> Type2 (i × j) --- data Pair2 p q a b where --- Pair2 :: p a0 b0 -> q a1 b1 -> Pair2 p q '(a0, a1) '(b0, b1) - --- type (×^^) = Pair2 --- infixl 7 ×^^ - --- type Either2 :: forall i j. Type2 i -> Type2 j -> Type2 (i + j) --- data Either2 p q a b where --- L2 :: p a b -> Either2 p q (L a) (L b) --- R2 :: q a b -> Either2 p q (R a) (R b) - --- type (+^^) = Either2 --- infixl 6 +^^ - -------------------------------------------------------------------------------- type Cat i = i -> i -> Type @@ -57,53 +38,51 @@ instance Category Hask where -------------------------------------------------------------------------------- --- type ProdOb :: Cat i -> Cat j -> i × j -> Constraint --- class ProdOb p q a where --- prodOb :: PairEvidence1 (Ob p) (Ob q) a --- instance (Ob p i, Ob q j) => ProdOb p q '(i, j) where --- prodOb = Pair1 Evidence1 Evidence1 +type Prod :: forall i j. Cat i -> Cat j -> Cat (i × j) +data Prod p q a b where + Prod :: p a0 b0 -> q a1 b1 -> Prod p q '(a0, a1) '(b0, b1) --- instance (Category p, Category q) => Category (p ×^^ q) where --- -- type Ob (p ×^^ q) = ProdOb p q --- type Ob (p ×^^ q) = HasPairEvidence1 (Ob p) (Ob q) --- identity @a = case pairEvidence @_ @_ @(Ob p) @(Ob q) @a of --- Pair1 Evidence1 Evidence1 -> Pair2 identity identity --- compose (Pair2 f0 f1) (Pair2 g0 g1) = Pair2 (compose f0 g0) (compose f1 g1) +-- We could simplify this, but this way it's consistent with SumOb. +type ProdOb :: forall i j. Cat i -> Cat j -> Constraint1 (i × j) +class ProdOb p q a where + prodOb :: Pair1 (Evidence1 (Ob p)) (Evidence1 (Ob q)) a +instance (Ob p i, Ob q j) => ProdOb p q '(i, j) where + prodOb = Pair1 Evidence1 Evidence1 --------------------------------------------------------------------------------- - --- type SumOb :: Cat i -> Cat j -> i + j -> Constraint --- class SumOb p q a where --- sumOb :: EitherEvidence1 (Ob p) (Ob q) a --- instance (Category p, Ob p a) => SumOb p q (L a) where --- sumOb = L1 Evidence1 --- instance (Category q, Ob q a) => SumOb p q (R a) where --- sumOb = R1 Evidence1 - --- instance (Category p, Category q) => Category (p +^^ q) where --- type Ob (p +^^ q) = SumOb p q --- identity @a = case sumOb @_ @_ @p @q @a of --- L1 Evidence1 -> L2 identity --- R1 Evidence1 -> R2 identity --- compose (L2 f) (L2 g) = L2 (compose f g) --- compose (R2 f) (R2 g) = R2 (compose f g) +instance (Category p, Category q) => Category (Prod p q) where + type Ob (Prod p q) = ProdOb p q + identity @a = case prodOb @_ @_ @p @q @a of + Pair1 Evidence1 Evidence1 -> Prod identity identity + compose (Prod f0 f1) (Prod g0 g1) = Prod (compose f0 g0) (compose f1 g1) -------------------------------------------------------------------------------- --- type PairEvidence1 :: forall i j. Constraint1 i -> Constraint1 j -> Type1 (i × j) --- type PairEvidence1 p q = Pair1 (Evidence1 p) (Evidence1 q) - --- type HasPairEvidence1 :: forall i j. Constraint1 i -> Constraint1 j -> Constraint1 (i × j) --- class HasPairEvidence1 p q a where --- pairEvidence :: PairEvidence1 p q a - --- type EitherEvidence1 :: forall i j. Constraint1 i -> Constraint1 j -> Type1 (i + j) --- type EitherEvidence1 p q = Either1 (Evidence1 p) (Evidence1 q) +type Sum :: forall i j. Cat i -> Cat j -> Cat (i + j) +data Sum p q a b where + SumL :: p a b -> Sum p q (L a) (L b) + SumR :: q a b -> Sum p q (R a) (R b) + +type SumOb :: forall i j. Cat i -> Cat j -> Constraint1 (i + j) +class SumOb p q a where + sumOb :: Either1 (Evidence1 (Ob p)) (Evidence1 (Ob q)) a +instance (Ob p a) => SumOb p q (L a) where + sumOb = L1 Evidence1 +instance (Ob q a) => SumOb p q (R a) where + sumOb = R1 Evidence1 + +instance (Category p, Category q) => Category (Sum p q) where + type Ob (Sum p q) = SumOb p q + identity @a = case sumOb @_ @_ @p @q @a of + L1 Evidence1 -> SumL identity + R1 Evidence1 -> SumR identity + compose (SumL f) (SumL g) = SumL (compose f g) + compose (SumR f) (SumR g) = SumR (compose f g) -------------------------------------------------------------------------------- type Nt :: forall i j. Cat i -> Cat j -> Cat (i -> j) -newtype Nt p q f g = Nt (forall a. (Ob p a) => q (f a) (g a)) +newtype Nt p q f g where + Nt :: (forall a. (Ob p a) => q (f a) (g a)) -> Nt p q f g type NtOb :: Cat i -> Cat j -> (i -> j) -> Constraint class (Functor f, Dom f ~ p, Cod f ~ q) => NtOb p q f