lude

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

commit 346f45333abdf8571385892aa1547d8202c213f0
parent b91992333672bdeaf9c6749b62ded2023baac0e4
Author: Robert Russell <robert@rr3.xyz>
Date:   Wed,  9 Sep 2026 17:55:21 -0700

Algebra.Category: add Iso

Diffstat:
Msrc/Lude.hs | 42------------------------------------------
Msrc/Lude/Algebra/Category.hs | 11++++++-----
Asrc/Lude/Algebra/Category/Iso.hs | 39+++++++++++++++++++++++++++++++++++++++
3 files changed, 45 insertions(+), 47 deletions(-)

diff --git a/src/Lude.hs b/src/Lude.hs @@ -366,39 +366,6 @@ newtype Fix2 f i j = Fix2 (f (Fix2 f i j) i j) {- -class Category (mor :: obj -> obj -> TypeL) where - -- If we make morphisms representation-polymorphic, we must modify identity: - -- {-# MINIMAL (identity | identityU), compose #-} - -- identity :: (ρ ~ LRep) => mor a a - -- identity = force identityU - -- identityU :: Thunk (mor a a) - -- default identityU :: (ρ ~ LRep) => Thunk (mor a a) - -- identityU () = identity - identity :: mor a a - compose :: mor b c -> mor a b -> mor a c - -class (Category (DomOf f)) => Functor (f :: domObj -> Type ρ) where - type DomOf f :: domObj -> domObj -> TypeL - map :: DomOf f a b -> (f a -> f b) - -class (Category (LDomOf f)) => LFunctor (f :: lDomObj -> k -> Type ρ) where - type LDomOf f :: lDomObj -> lDomObj -> TypeL - - mapl :: LDomOf f a b -> (f a c -> f b c) - default mapl :: (Bifunctor f) => LDomOf f a b -> (f a c -> f b c) - mapl = flip bimap identity - -class (Category (RDomOf f)) => RFunctor (f :: k -> rDomObj -> Type ρ) where - type RDomOf f :: rDomObj -> rDomObj -> TypeL - - mapr :: RDomOf f a b -> (f c a -> f c b) - default mapr :: (Bifunctor f) => RDomOf f a b -> (f c a -> f c b) - mapr = bimap identity - -class (LFunctor f, RFunctor f, Category (Hask ρ)) => Bifunctor (f :: lDomObj -> rDomObj -> Type ρ) where - bimap :: LDomOf f a b -> RDomOf f c d -> (f a c -> f b d) - bimap f g = mapl f ∘ mapr g - type Iso (mor :: obj -> obj -> TypeL) a b = (mor a b, mor b a) -- TODO: use strict pair class (Bifunctor f, LDomOf f ~ Hask ρ, RDomOf f ~ Hask ρ) => Monoidal (f :: Type ρ -> Type ρ -> Type ρ) where @@ -420,15 +387,6 @@ class (Monoidal f) => Cartesian (f :: Type ρ -> Type ρ -> Type ρ) where diag :: forall (a :: Type ρ). a -> f a a diag = pair identity identity -type Hask ρ = (->) :: Type ρ -> Type ρ -> TypeL - -instance Category (Hask RepL) where - identity x = x - compose f g x = f (g x) - -(∘) :: (Category mor) => mor b c -> mor a b -> mor a c -(∘) = compose - -} -- | Right-to-left composition. diff --git a/src/Lude/Algebra/Category.hs b/src/Lude/Algebra/Category.hs @@ -3,17 +3,16 @@ module Lude.Algebra.Category ( ) where import Lude.Algebra.Category.Bifunctor as X +import Lude.Algebra.Category.Constrained as X import Lude.Algebra.Category.Core as X import Lude.Algebra.Category.Discrete as X import Lude.Algebra.Category.Hom as X import Lude.Algebra.Category.Initial as X +import Lude.Algebra.Category.Iso as X +import Lude.Algebra.Category.Monad as X import Lude.Algebra.Category.Terminal as X --- TODO: Semicategory? - --- TODO: Filterable is functor from Kleisli Option to Hask - --- TODO: Monads and comonads +-- TODO: Semicategory? Semimonad? Etc... See semigroups package. -- TODO: Free and cofree @@ -24,3 +23,5 @@ import Lude.Algebra.Category.Terminal as X -- TODO: Profunctors? Other special kinds of functors, given distinct names? -- That would allow being a functor in multiple ways without losing coherence. -- E.g., lists could be mappable "normally" and filterable (choose is map). + +-- TODO: Filterable is functor from Kleisli Option to Hask diff --git a/src/Lude/Algebra/Category/Iso.hs b/src/Lude/Algebra/Category/Iso.hs @@ -0,0 +1,39 @@ +module Lude.Algebra.Category.Iso ( + Iso (..), +) where + +import Lude.Algebra.Category.Core +import Lude.Haskell + +-- TODO: Iso is a groupoid. + +-------------------------------------------------------------------------------- + +-- | An isomorphism (in some category) +-- +-- In other words, @Iso p@ is the *core* of @p@. +-- +-- Laws: +-- - @to . fro = identity@ +-- - @fro . to = identity@ +type Iso :: forall {i}. Cat i -> Cat i +data Iso p a b = MkIso {to :: a `p` b, fro :: b `p` a} + +instance (Categorical p) => Iso p a b `Witnesses` Mor (Iso p) a b where + witness (MkIso f _) = MkEvidence \\ witnessMor f + +instance (Categorical p) => Categorical (Iso p) where + type Obj (Iso p) = Obj p + identity = MkIso identity identity + compose (MkIso f0 f1) (MkIso g0 g1) = MkIso (f0 . g0) (g1 . f1) + witnessMor = witness + +instance (Categorical p) => Functorial (Iso p a) where + type Dom (Iso p a) = Iso p + type Cod (Iso p a) = Function + map = compose + +instance (Categorical p) => Functorial (Iso p) where + type Dom (Iso p) = Dual (Iso p) + type Cod (Iso p) = Iso p ==> Function + map (MkDual f) = Natural (. f)