packages feed

some 1.0.4.1 → 1.0.5

raw patch · 6 files changed

+217/−11 lines, 6 filesdep ~basedep ~deepseq

Dependency ranges changed: base, deepseq

Files

ChangeLog.md view
@@ -1,3 +1,30 @@+# 1.0.5++- Add EqP and OrdP classes.+  These are strong versions of Eq1 and Ord1, and on the other hand+  weaker versions of `GEq` and `GCompare`.+  They are exactly what's needed for `Eq` and `Ord` instances of `Some`.++  The naming is unfortunate: `GShow` would be better named `ShowP`,+  as it's similar version of `Show1`.++  Note: we could add `ReadP` with `readsPrecP :: Int -> ReadS (t a)` method,+  but it will barely have any instances.+  `GRead` is different, as it can reify the type index for many types,+  e.g. for the singletons.++  In some future there will be major version of `some` with following+  breaking changes:+  - `EqP` and `OrdP` will become superclasses of `GEq` and `GCompare`+  - `Eq (Some t)` will require `EqP t`, similarly for `Ord` and `OrdP`.+  - `GShow` will get `forall a. Show (f a)` superclass. (This will cause removal of `Product` and `Sum` instances for `base <4.18`).++  To ease future transition you may+  - Define `EqP` and `OrdP` instances for your types.+    The `defaultEq` and `defaultCompare` methods can be used to define+    `eqp` and `comparep` from `GEq` and `GCompare` instances respectively.+  - Move to use `GHC.Generics.:*:` and `:+:` instead of `Data.Functor.Product` and `Sum`, as these have better `Eq` and `Ord` instances.+ # 1.0.4.1  - Drop support for GHC before 8.6
some.cabal view
@@ -1,5 +1,5 @@ name:               some-version:            1.0.4.1+version:            1.0.5 cabal-version:      >=1.10 build-type:         Simple author:@@ -24,12 +24,7 @@   If you are unsure which variant to use, use the one in "Data.Some" module.  tested-with:-  GHC ==8.6.5-   || ==8.8.4-   || ==8.10.4-   || ==9.0.2-   || ==9.2.4-   || ==9.4.2+  GHC ==8.6.5 || ==8.8.4 || ==8.10.4 || ==9.0.2 || ==9.2.7|| ==9.4.4 || ==9.6.1  extra-source-files: ChangeLog.md @@ -42,7 +37,7 @@  source-repository head   type:     git-  location: git://github.com/haskellari/some.git+  location: https://github.com/haskellari/some.git   subdir:   some  library@@ -55,16 +50,18 @@   -- main module   exposed-modules:  Data.Some   exposed-modules:+    Data.EqP     Data.GADT.Compare     Data.GADT.DeepSeq     Data.GADT.Show+    Data.OrdP     Data.Some.Church     Data.Some.GADT     Data.Some.Newtype    other-modules:    Data.GADT.Internal   build-depends:-      base     >=4.12    && <4.18+      base     >=4.12    && <4.19     , deepseq  >=1.4.4.0 && <1.5    if impl(ghc >=9.0)
+ src/Data/EqP.hs view
@@ -0,0 +1,98 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE QuantifiedConstraints #-}+{-# LANGUAGE Safe                  #-}+{-# LANGUAGE TypeOperators         #-}+#if __GLASGOW_HASKELL__ >= 810+{-# LANGUAGE StandaloneKindSignatures #-}+#endif+module Data.EqP (+    EqP (..),+) where++import Control.Applicative   (Const (..))+import Data.Kind             (Type)+import Data.Proxy            (Proxy (..))+import Data.Type.Equality    ((:~:) (..), (:~~:) (..))+import GHC.Generics          ((:*:) (..), (:+:) (..))+import System.Mem.StableName (StableName, eqStableName)++#if MIN_VERSION_base(4,18,0)+import Data.Functor.Product (Product (..))+import Data.Functor.Sum (Sum (..))+#endif++import qualified Type.Reflection as TR++#if __GLASGOW_HASKELL__ >= 810+import Data.Kind (Constraint)+#endif++-- | Heterogenous lifted equality.+--+-- This class is stronger version of 'Eq1' from @base@+--+-- @+-- class (forall a. Eq a => Eq (f a)) => Eq1 f where+--     liftEq :: (a -> b -> Bool) -> f a -> f b -> Bool+-- @+--+-- as we don't require a @a -> b -> Bool@ function.+--+-- Morally 'Eq1' should be a superclass of 'EqP', but it cannot be,+-- as GHC wouldn't allow 'EqP' to be polykinded.+-- https://gitlab.haskell.org/ghc/ghc/-/issues/22682+--+-- == Laws+--+-- [reflexivity]    @'eqp' x x ≡ True@+-- [symmetry]       @'eqp' x y ≡ 'eqp' y x@+-- [transitivity]   @'eqp' x y ≡ 'eqp' y z ≡ True ⇒ 'eqp' x z ≡ True@+-- [compatibility]  @'eqp' x y ≡ x '==' y@+-- [extensionality] @'eqp' x y ≡ True ⇒ f x == f y ≡ True@ for polymorphic @f :: forall x. f x -> a@ and @'Eq' a@.+--+-- /Note:/ P stands for phantom.+--+-- @since 1.0.5+#if __GLASGOW_HASKELL__ >= 810+type EqP :: (k -> Type) -> Constraint+#endif+class (forall a. Eq (f a)) => EqP (f :: k -> Type) where+    eqp :: f a -> f b -> Bool++instance EqP ((:~:) a) where+    eqp _ _ = True++instance EqP ((:~~:) a) where+    eqp _ _ = True+++#if MIN_VERSION_base(4,18,0)+instance (EqP a, EqP b) => EqP (Sum a b) where+    eqp (InL x) (InL y) = eqp x y+    eqp (InR x) (InR y) = eqp x y+    eqp _ _ = False++instance (EqP a, EqP b) => EqP (Product a b) where+    eqp (Pair x y) (Pair x' y') = eqp x x' && eqp y y'+#endif++instance (EqP f, EqP g) => EqP (f :+: g) where+    eqp (L1 x) (L1 y) = eqp x y+    eqp (R1 x) (R1 y) = eqp x y+    eqp _ _ = False++instance (EqP a, EqP b) => EqP (a :*: b) where+    eqp (x :*: y) (x' :*: y') = eqp x x' && eqp y y'++instance EqP TR.TypeRep where+    eqp x y = TR.SomeTypeRep x == TR.SomeTypeRep y++instance EqP Proxy where+    eqp _ _ = True++instance Eq a => EqP (Const a) where+    eqp (Const x) (Const y) = x == y++instance EqP StableName where+    eqp = eqStableName
+ src/Data/OrdP.hs view
@@ -0,0 +1,82 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE QuantifiedConstraints #-}+{-# LANGUAGE Safe                  #-}+{-# LANGUAGE TypeOperators         #-}+#if __GLASGOW_HASKELL__ >= 810+{-# LANGUAGE StandaloneKindSignatures #-}+#endif+module Data.OrdP (+    OrdP (..),+) where++import Control.Applicative  (Const (..))+import Data.Kind            (Type)+import Data.Proxy           (Proxy (..))+import Data.Semigroup       ((<>))+import Data.Type.Equality   ((:~:) (..), (:~~:) (..))+import GHC.Generics         ((:*:) (..), (:+:) (..))++#if MIN_VERSION_base(4,18,0)+import Data.Functor.Product (Product (..))+import Data.Functor.Sum (Sum (..))+#endif++import qualified Type.Reflection as TR++#if __GLASGOW_HASKELL__ >= 810+import Data.Kind (Constraint)+#endif++import Data.EqP++-- | Heterogenous lifted total order.+--+-- This class is stronger version of 'Ord1' from @base@+--+-- @+-- class (forall a. Ord a => Ord (f a)) => Ord1 f where+--     liftCompare :: (a -> b -> Ordering) -> f a -> f b -> Ordering+-- @+--+-- @since 1.0.5+#if __GLASGOW_HASKELL__ >= 810+type OrdP :: (k -> Type) -> Constraint+#endif+class (EqP f, forall a. Ord (f a)) => OrdP (f :: k -> Type) where+    comparep :: f a -> f b -> Ordering++instance OrdP ((:~:) a) where+    comparep _ _ = EQ++instance OrdP ((:~~:) a) where+    comparep _ _ = EQ++#if MIN_VERSION_base(4,18,0)+instance (OrdP a, OrdP b) => OrdP (Sum a b) where+    comparep (InL x) (InL y) = comparep x y+    comparep (InL _) (InR _) = LT+    comparep (InR x) (InR y) = comparep x y+    comparep (InR _) (InL _) = GT++instance (OrdP a, OrdP b) => OrdP (Product a b) where+    comparep (Pair x y) (Pair x' y') = comparep x x' <> comparep y y'+#endif++instance (OrdP f, OrdP g) => OrdP (f :+: g) where+    comparep (L1 x) (L1 y) = comparep x y+    comparep (L1 _) (R1 _) = LT+    comparep (R1 x) (R1 y) = comparep x y+    comparep (R1 _) (L1 _) = GT++instance (OrdP a, OrdP b) => OrdP (a :*: b) where+    comparep (x :*: y) (x' :*: y') = comparep x x' <> comparep y y'++instance OrdP TR.TypeRep where+    comparep x y = compare (TR.SomeTypeRep x) (TR.SomeTypeRep y)++instance OrdP Proxy where+    comparep _ _ = EQ++instance Ord a => OrdP (Const a) where+    comparep (Const x) (Const y) = compare x y
src/Data/Some/GADT.hs view
@@ -34,10 +34,11 @@ -- $setup -- >>> :set -XKindSignatures -XGADTs -- >>> import Data.GADT.Show+-- >>> import Data.Kind (Type)  -- | Existential. This is type is useful to hide GADTs' parameters. ----- >>> data Tag :: * -> * where TagInt :: Tag Int; TagBool :: Tag Bool+-- >>> data Tag :: Type -> Type where TagInt :: Tag Int; TagBool :: Tag Bool -- >>> instance GShow Tag where gshowsPrec _ TagInt = showString "TagInt"; gshowsPrec _ TagBool = showString "TagBool" -- >>> classify s = case s of "TagInt" -> [mkGReadResult TagInt]; "TagBool" -> [mkGReadResult TagBool]; _ -> [] -- >>> instance GRead Tag where greadsPrec _ s = [ (r, rest) | (con, rest) <-  lex s, r <- classify con ]
src/Data/Some/Newtype.hs view
@@ -36,10 +36,11 @@ -- $setup -- >>> :set -XKindSignatures -XGADTs -- >>> import Data.GADT.Show+-- >>> import Data.Kind (Type)  -- | Existential. This is type is useful to hide GADTs' parameters. ----- >>> data Tag :: * -> * where TagInt :: Tag Int; TagBool :: Tag Bool+-- >>> data Tag :: Type -> Type where TagInt :: Tag Int; TagBool :: Tag Bool -- >>> instance GShow Tag where gshowsPrec _ TagInt = showString "TagInt"; gshowsPrec _ TagBool = showString "TagBool" -- >>> classify s = case s of "TagInt" -> [mkGReadResult TagInt]; "TagBool" -> [mkGReadResult TagBool]; _ -> [] -- >>> instance GRead Tag where greadsPrec _ s = [ (r, rest) | (con, rest) <-  lex s, r <- classify con ]