From 53a850469af4a8db0d823816ffbc04b1f5bba802 Mon Sep 17 00:00:00 2001 From: bruderj15 Date: Fri, 29 Nov 2024 18:12:45 +0100 Subject: [PATCH 1/5] somef: added type-aliases for existential containers --- src/Data/Some/Constraint.hs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Data/Some/Constraint.hs b/src/Data/Some/Constraint.hs index c709e58..6b03c54 100644 --- a/src/Data/Some/Constraint.hs +++ b/src/Data/Some/Constraint.hs @@ -57,6 +57,12 @@ data Somes1 csf csa where -- | Alias for 'Somes1' with just one 'Constraint'. type Some1 cf ca = Somes1 '[cf] '[ca] +-- | Alias for 'Somes1' with a container @f@ and multple 'Constraint's @csa@ for its elements. +type SomesF f csa = Somes1 '[(~) f] csa + +-- | Alias for 'SomeF' with just one 'Constraint' for its elements. +type SomeF f c = SomesF f '[c] + instance {-# OVERLAPPING #-} Show (Somes (Show ': cs)) where showsPrec d (Some x) = showParen (d > 10) $ showString "Some " . showsPrec 11 x From 08def14e7fec6332067c967f08a94f8f984e1096 Mon Sep 17 00:00:00 2001 From: bruderj15 Date: Fri, 29 Nov 2024 19:03:01 +0100 Subject: [PATCH 2/5] somef: added mapSome and traverseSome --- src/Data/Some/Constraint.hs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Data/Some/Constraint.hs b/src/Data/Some/Constraint.hs index 6b03c54..840922b 100644 --- a/src/Data/Some/Constraint.hs +++ b/src/Data/Some/Constraint.hs @@ -9,6 +9,7 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE RankNTypes #-} module Data.Some.Constraint where @@ -57,12 +58,30 @@ data Somes1 csf csa where -- | Alias for 'Somes1' with just one 'Constraint'. type Some1 cf ca = Somes1 '[cf] '[ca] --- | Alias for 'Somes1' with a container @f@ and multple 'Constraint's @csa@ for its elements. +-- | Alias for 'Somes1' with a container @f@ and multiple 'Constraint's @csa@ for its elements. type SomesF f csa = Somes1 '[(~) f] csa -- | Alias for 'SomeF' with just one 'Constraint' for its elements. type SomeF f c = SomesF f '[c] +-- | Natural transformation of one container to another. +mapSome :: (forall a. AllC csa a => f a -> g a) -> SomesF f csa -> SomesF g csa +mapSome f (Some1 x) = Some1 (f x) + +infixl 4 <~$> +-- | Infix version of 'mapSome'. +(<~$>) :: (forall a. AllC csa a => f a -> g a) -> SomesF f csa -> SomesF g csa +(<~$>) = mapSome + +-- | Natural transformation of one container to another - with side effects in @m@. +traverseSome :: Functor m => (forall a. AllC csa a => f a -> m (g a)) -> SomesF f csa -> m (SomesF g csa) +traverseSome f (Some1 x) = Some1 <$> f x + +infixl 4 <~*> +-- | Infix version of 'traverseSome'. +(<~*>) :: Functor m => (forall a. AllC csa a => f a -> m (g a)) -> SomesF f csa -> m (SomesF g csa) +(<~*>) = traverseSome + instance {-# OVERLAPPING #-} Show (Somes (Show ': cs)) where showsPrec d (Some x) = showParen (d > 10) $ showString "Some " . showsPrec 11 x From 10951fb9797daac79612a3ce0650dca6a73876f5 Mon Sep 17 00:00:00 2001 From: bruderj15 Date: Fri, 29 Nov 2024 19:31:10 +0100 Subject: [PATCH 3/5] somef: instance Show for SomeF --- src/Data/Some/Constraint.hs | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/Data/Some/Constraint.hs b/src/Data/Some/Constraint.hs index 840922b..0930131 100644 --- a/src/Data/Some/Constraint.hs +++ b/src/Data/Some/Constraint.hs @@ -10,8 +10,26 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE RankNTypes #-} +{-# LANGUAGE QuantifiedConstraints #-} -module Data.Some.Constraint where +module Data.Some.Constraint +( + -- * Combining constraints + AllC + + -- * Existentials + -- ** Flat existentials + , Somes(..), Some + + -- ** Containerized existentials + -- *** Constrained containers + , Somes1(..), Some1 + + -- *** Fixed containers + , SomesF, SomeF + , mapSome, (<~$>) + , traverseSome, (<~*>) +) where import Data.Kind @@ -35,6 +53,12 @@ data Somes cs where (a :: Type). AllC cs a => a -> Somes cs +instance {-# OVERLAPPING #-} Show (Somes (Show ': cs)) where + showsPrec d (Some x) = showParen (d > 10) $ showString "Some " . showsPrec 11 x + +instance {-# OVERLAPPABLE #-} Show (Somes cs) => Show (Somes (c ': cs)) where + showsPrec d (Some x) = showsPrec d (Some @cs x) + -- | Alias for 'Somes' with just one 'Constraint'. type Some c = Somes '[c] @@ -82,8 +106,8 @@ infixl 4 <~*> (<~*>) :: Functor m => (forall a. AllC csa a => f a -> m (g a)) -> SomesF f csa -> m (SomesF g csa) (<~*>) = traverseSome -instance {-# OVERLAPPING #-} Show (Somes (Show ': cs)) where - showsPrec d (Some x) = showParen (d > 10) $ showString "Some " . showsPrec 11 x +instance {-# OVERLAPPING #-} (forall a. Show a => Show (f a)) => Show (SomesF f (Show ': cs)) where + showsPrec d (Some1 x) = showParen (d > 10) $ showString "Some " . showsPrec 11 x -instance {-# OVERLAPPABLE #-} Show (Somes cs) => Show (Somes (c ': cs)) where - showsPrec d (Some x) = showsPrec d (Some @cs x) +instance {-# OVERLAPPABLE #-} Show (SomesF f cs) => Show (SomesF f (c ': cs)) where + showsPrec d (Some1 x) = showsPrec d (Some1 @_ @('[(~) f]) @cs x) From 9f0b2e44a873521bf1862762f3b3b1024bcd090b Mon Sep 17 00:00:00 2001 From: bruderj15 Date: Fri, 29 Nov 2024 19:56:39 +0100 Subject: [PATCH 4/5] somef: update README --- README.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e837654..837c0c9 100644 --- a/README.md +++ b/README.md @@ -7,19 +7,25 @@ It allows you to enforce multiple constraints on polymorphic types and container ## Core -- **Existential Types**: `Somes` and `Somes1` provide existential wrappers for types with multiple constraints. -- **Convenient Aliases**: Simplified types `Some` and `Some1` for scenarios where just one constraint is needed. - +- **Existential types**: `Somes` and `Somes1` provide existential wrappers for types with multiple constraints. +- **Convenient aliases**: Simplified types `Some` and `Some1` for scenarios where just one constraint is needed. +- **More convenient aliases**: Simplified types `SomeF` and `SomesF` for scenarios where the container of a `Somes1` is known. +- **Natural transformations with constraints** + - `mapSome :: (forall a. AllC csa a => f a -> g a) -> SomesF f csa -> SomesF g csa` + - `traverseSome :: Functor m => (forall a. AllC csa a => f a -> m (g a)) -> SomesF f csa -> m (SomesF g csa)` ## Usage ```haskell import Data.Some.Constraint someShowableOrd :: Somes '[Show, Ord] -someShowableOrd = Some (mempty :: [Double]) +someShowableOrd = Some [1, 2, 3 :: Int] someNumFunctor :: Some1 Functor Num -someNumFunctor = Some1 $ [1, 2, 3 :: Int] +someNumFunctor = Some1 [1, 2, 3 :: Int] + +someListShowable :: SomeF [] Show +someListShowable = Some1 [1, 2, 3 :: Int] ``` ## Contact information From 8706a16bc16209c9a81fb3416583d4e3ef7e3758 Mon Sep 17 00:00:00 2001 From: bruderj15 Date: Fri, 29 Nov 2024 19:59:36 +0100 Subject: [PATCH 5/5] somef: bump version --- CHANGELOG.md | 6 ++++++ constrained-some.cabal | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb49b2b..b1fa457 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [PVP versioning](https://pvp.haskell.org/). +## v0.1.2 _(2024-11-29)_ + +### Added +- Added type aliases `SomesF` and `SomeF` for existentials with fixed containers +- Added `mapSome` with infix `(<~$>)` and `traverseSome` with infix `(<~*>)` + ## v0.1.1 _(2024-11-29)_ ### Added diff --git a/constrained-some.cabal b/constrained-some.cabal index 7b5e938..9cfb201 100644 --- a/constrained-some.cabal +++ b/constrained-some.cabal @@ -1,6 +1,6 @@ cabal-version: 3.0 name: constrained-some -version: 0.1.1 +version: 0.1.2 synopsis: Existential type that can be constrained description: This library provides utilities for working with existential types and type-level constraints. It allows you to enforce multiple constraints on polymorphic types and containers complementing the package some.