lude

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

commit 581a05b0802017cb1c3d34a2e9d73feddb9a4039
parent a8877191187dc9bc99ce0dba251579d521cd89b6
Author: Robert Russell <robert@rr3.xyz>
Date:   Thu,  3 Sep 2026 00:13:21 -0700

WIP

Diffstat:
Msrc/Lude/Algebra.hs | 2+-
Msrc/Lude/Algebra/Category.hs | 24++++++++++++++++++++++--
Asrc/Lude/Bool.hs | 9+++++++++
Msrc/Lude/Kind.hs | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/Lude/Pair.hs | 56+++++++++++++++++++++++++++++++++++++++++++++++++-------
5 files changed, 134 insertions(+), 10 deletions(-)

diff --git a/src/Lude/Algebra.hs b/src/Lude/Algebra.hs @@ -11,7 +11,7 @@ module Lude.Algebra ( import Data.Set (Set) import Data.Set qualified as Set -import Prelude (Eq, Ord) +import Prelude (Ord) import Lude.Kind import Lude.Repr (Repr) diff --git a/src/Lude/Algebra/Category.hs b/src/Lude/Algebra/Category.hs @@ -13,7 +13,9 @@ import Lude.Kind import Lude.Pair -- TODO: Semicategory + -- TODO: Allow non-BoxL morphism Repr? + -- TODO: Filterable is functor from Kleisli Option to Hask -------------------------------------------------------------------------------- @@ -38,15 +40,25 @@ instance Category Hask where -------------------------------------------------------------------------------- +type Dual :: forall i. Cat i -> Cat i +newtype Dual p a b = Dual (p b a) + +instance (Category p) => Category (Dual p) where + type Obj (Dual p) = Obj p + identity = Dual identity + compose (Dual f) (Dual g) = Dual (compose g f) + +-------------------------------------------------------------------------------- + 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) + Prod :: p a0 b0 -> q a1 b1 -> Prod p q (a0, a1) (b0, b1) -- We could simplify this, but this way it's consistent with SumObj. type ProdObj :: forall i j. Cat i -> Cat j -> Constraint1 (i × j) class ProdObj p q a where prodObj :: Pair1 (Evidence1 (Obj p)) (Evidence1 (Obj q)) a -instance (Obj p i, Obj q j) => ProdObj p q '(i, j) where +instance (Obj p i, Obj q j) => ProdObj p q (i, j) where prodObj = Pair1 Evidence1 Evidence1 instance (Category p, Category q) => Category (Prod p q) where @@ -112,6 +124,9 @@ class (Category (Dom f), Category (Cod f)) => Functor (f :: i -> j) where map :: Dom f a b -> Cod f (f a) (f b) +instance Functor (Pair b) where + map f (b, a) = (b, f a) + instance Functor (Either b) where map _ (L b) = L b map f (R a) = R (f a) @@ -124,7 +139,12 @@ instance Functor (Either b) where -- type Bifunctor :: forall i j k. (i -> j -> k) -> Constraint -- class (Category (Bildom f), Category (Birdom f), Category (Bicod f)) => Bifunctor (f :: i -> j -> k) where -- type Bildom f :: Cat i +-- type Bildom f = DefaultCat + -- type Birdom f :: Cat j +-- type Birdom f = DefaultCat + -- type Bicod f :: Cat k +-- type Bicod f = DefaultCat -- lmap :: Bildom f a b -> diff --git a/src/Lude/Bool.hs b/src/Lude/Bool.hs @@ -0,0 +1,9 @@ +module Lude.Bool ( + Bool (..), +) where + +import Data.Bool (Bool (..)) + +-- TODO: Instances + +-------------------------------------------------------------------------------- diff --git a/src/Lude/Kind.hs b/src/Lude/Kind.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE UndecidableInstances #-} + module Lude.Kind ( Kind, (:~:) (..), @@ -42,6 +44,9 @@ type TypeU = Type @Repr.BoxU type Type1 :: forall (r :: Repr). Kind -> Kind type Type1 @r i = i -> Type @r +type AnyType :: Kind +data AnyType = forall (r :: Repr). MkAnyType (Type @r) + -------------------------------------------------------------------------------- type Constraint :: forall (r :: Repr). Kind @@ -71,3 +76,51 @@ type Endo k = k -> k type BiEndo :: Kind -> Kind type BiEndo k = k -> k -> k + +-------------------------------------------------------------------------------- + +-- | An empty kind with a phantom kind index, used to make @T k@ opaque +type T' :: Kind -> Kind +data T' k + +-- | A type expression (of a given kind) +type T :: Kind -> Kind +type T k = T' k -> Kind + +type Splice :: forall {k}. T k -> k +type family Splice _ + +data Quote :: forall {k}. k -> T k +type instance Splice (Quote a) = a + +-- | Defunctionalized @(->)@ +type (-->) :: Kind -> Kind -> Kind +type k --> l = k -> T l + +infixr 1 --> + +type Apply :: forall {k} {l}. (k --> l) -> k -> l +type Apply f a = Splice (f a) + +type (@@) :: forall {k} {l}. (k --> l) -> k -> l +type f @@ a = Apply f a +infixl 7 @@ + +type Defun = Defun1 +data Defun1 :: forall k0 k. (k0 -> k) -> (k0 --> k) +type instance Splice (Defun1 f a) = f a + +data Defun2 :: forall k0 k1 k. (k0 -> k1 -> k) -> (k0 --> k1 --> k) +type instance Splice (Defun2 f a) = Defun1 (f a) + +data Defun3 :: forall k0 k1 k2 k. (k0 -> k1 -> k2 -> k) -> (k0 --> k1 --> k2 --> k) +type instance Splice (Defun3 f a) = Defun2 (f a) + +data Defun4 :: forall k0 k1 k2 k3 k. (k0 -> k1 -> k2 -> k3 -> k) -> (k0 --> k1 --> k2 --> k3 --> k) +type instance Splice (Defun4 f a) = Defun3 (f a) + +type Ident :: forall {k}. k --> k +type Ident = Quote + +data Compose :: forall {k} {l} {m}. (l --> m) -> (k --> l) -> (k --> m) +type instance Splice (Compose f g x) = Splice (f (Splice (g x))) diff --git a/src/Lude/Pair.hs b/src/Lude/Pair.hs @@ -14,14 +14,56 @@ module Lude.Pair ( Snd, ) where +import GHC.Exts qualified as GHC +import Lude.Bool import Lude.Kind +import Lude.Repr (Repr) +import Lude.Repr qualified as Repr +import Prelude.Experimental qualified as GHC +import Prelude qualified --- TODO: Generalize fst and snd (and fst1 and snd1?) with Cartesian class +-- TODO: Generalize fst and snd (and fst1 and snd1?) with Cartesian class. +-- Probably name them outl and outr for symmetry with inl and inr. + +type HType :: Kind +data HType = forall (r :: Repr). HType (Type @r) + +type HRepr :: HType -> Repr +type family HRepr _ where + HRepr ('HType @r _) = r + +type UnHType :: forall (h :: HType) -> Type @(HRepr h) +type family UnHType _ where + UnHType ('HType a) = a + +type ProdRepr :: GHC.List HType -> Repr +type family ProdRepr _ where + ProdRepr [] = GHC.TupleRep [] + ProdRepr (h : hs) = GHC.TupleRep [HRepr h, ProdRepr hs] + +type Prod :: forall (hs :: GHC.List HType) -> Type @(ProdRepr hs) +type family Prod _ where + Prod [] = GHC.Tuple0# + +-- Prod (x ': xs) = (# UnHType x, Prod xs #) + +type Cool :: Type @(Repr.Tuple [Repr.Int, Repr.Tuple [Repr.BoxL, Repr.Tuple []]]) +type Cool = Prod ['HType GHC.Int#, 'HType GHC.Unit] + +type Tup :: GHC.List Type -> Type +type family Tup _ where + Tup [] = GHC.Tuple0 + Tup [a] = GHC.Tuple1 a + +-- 1. "raw" tuples (various arity); "raw" sums (various arity) +-- 2. "semantic" types implemented with those (Either, Both, etc.) + +data Shape = Shape Bool Bool Bool Bool -------------------------------------------------------------------------------- type Pair :: Type -> Type -> Type -type Pair = (,) +type Pair = GHC.Tuple2 -- For consistency pattern Pair :: a -> b -> Pair a b @@ -41,21 +83,21 @@ snd (Pair _ y) = y type Pair1 :: forall i j. Type1 i -> Type1 j -> Type1 (i × j) data Pair1 f g a where - Pair1 :: f a0 -> g a1 -> Pair1 f g '(a0, a1) + Pair1 :: f a0 -> g a1 -> Pair1 f g (a0, a1) type (×^) = Pair1 infixl 7 ×^ -fst1 :: Pair1 p q '(i, j) -> p i +fst1 :: Pair1 p q (i, j) -> p i fst1 (Pair1 x _) = x -snd1 :: Pair1 p q '(i, j) -> q j +snd1 :: Pair1 p q (i, j) -> q j snd1 (Pair1 _ y) = y -------------------------------------------------------------------------------- type family Fst (x :: i × j) :: i where - Fst '(a, b) = a + Fst (a, b) = a type family Snd (x :: i × j) :: j where - Snd '(a, b) = b + Snd (a, b) = b