generic-data 0.1.1.0 → 0.2.0.0
raw patch · 13 files changed
+99/−126 lines, 13 filesdep +base-orphansdep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: base-orphans
Dependency ranges changed: base
API changes (from Hackage documentation)
- Generic.Data.Internal.Data: instance Data.Semigroup.Semigroup (r p) => Data.Semigroup.Semigroup (Generic.Data.Internal.Data.Data r p)
- Generic.Data.Internal.Defun: data Const :: k2 -> TyFun k1 k2 -> Type
- Generic.Data.Internal.Defun: data Id :: TyFun k1 k2 -> Type
- Generic.Data.Internal.Defun: data TyCon :: (k1 -> k2) -> TyFun k1 k2 -> Type
- Generic.Data.Internal.Defun: data TyFun :: Type -> Type -> Type
- Generic.Data.Internal.Defun: type a ~> b = TyFun a b -> Type
- Generic.Data.Internal.Generically: instance (GHC.Generics.Generic a, Data.Semigroup.Semigroup (GHC.Generics.Rep a ())) => Data.Semigroup.Semigroup (Generic.Data.Internal.Generically.Generically a)
- Generic.Data.Internal.Prelude: from' :: Generic a => a -> Rep a ()
- Generic.Data.Internal.Prelude: liftG2 :: Generic1 f => (Rep1 f a -> Rep1 f b -> Rep1 f c) -> f a -> f b -> f c
- Generic.Data.Internal.Prelude: to' :: Generic a => Rep a () -> a
- Generic.Data.Orphans: instance (Data.Semigroup.Semigroup (f p), Data.Semigroup.Semigroup (g p)) => Data.Semigroup.Semigroup ((GHC.Generics.:*:) f g p)
- Generic.Data.Orphans: instance (GHC.Base.Monoid (f p), GHC.Base.Monoid (g p)) => GHC.Base.Monoid ((GHC.Generics.:*:) f g p)
- Generic.Data.Orphans: instance Data.Semigroup.Semigroup (GHC.Generics.U1 p)
- Generic.Data.Orphans: instance Data.Semigroup.Semigroup (GHC.Generics.V1 p)
- Generic.Data.Orphans: instance Data.Semigroup.Semigroup (f (g p)) => Data.Semigroup.Semigroup ((GHC.Generics.:.:) f g p)
- Generic.Data.Orphans: instance Data.Semigroup.Semigroup (f p) => Data.Semigroup.Semigroup (GHC.Generics.M1 i c f p)
- Generic.Data.Orphans: instance Data.Semigroup.Semigroup (f p) => Data.Semigroup.Semigroup (GHC.Generics.Rec1 f p)
- Generic.Data.Orphans: instance Data.Semigroup.Semigroup c => Data.Semigroup.Semigroup (GHC.Generics.K1 i c p)
- Generic.Data.Orphans: instance Data.Semigroup.Semigroup p => Data.Semigroup.Semigroup (GHC.Generics.Par1 p)
- Generic.Data.Orphans: instance GHC.Base.Monoid (GHC.Generics.U1 p)
- Generic.Data.Orphans: instance GHC.Base.Monoid (f (g p)) => GHC.Base.Monoid ((GHC.Generics.:.:) f g p)
- Generic.Data.Orphans: instance GHC.Base.Monoid (f p) => GHC.Base.Monoid (GHC.Generics.M1 i c f p)
- Generic.Data.Orphans: instance GHC.Base.Monoid (f p) => GHC.Base.Monoid (GHC.Generics.Rec1 f p)
- Generic.Data.Orphans: instance GHC.Base.Monoid c => GHC.Base.Applicative (GHC.Generics.K1 i c)
- Generic.Data.Orphans: instance GHC.Base.Monoid c => GHC.Base.Monoid (GHC.Generics.K1 i c p)
- Generic.Data.Orphans: instance GHC.Base.Monoid p => GHC.Base.Monoid (GHC.Generics.Par1 p)
- Generic.Data.Types: data Const :: k2 -> TyFun k1 k2 -> Type
- Generic.Data.Types: data Id :: TyFun k1 k2 -> Type
- Generic.Data.Types: data TyCon :: (k1 -> k2) -> TyFun k1 k2 -> Type
- Generic.Data.Types: data TyFun :: Type -> Type -> Type
- Generic.Data.Types: type a ~> b = TyFun a b -> Type
+ Generic.Data.Internal.Data: fromData :: Generic a => Data (Rep a) p -> a
+ Generic.Data.Internal.Data: instance GHC.Base.Semigroup (r p) => GHC.Base.Semigroup (Generic.Data.Internal.Data.Data r p)
+ Generic.Data.Internal.Data: toData :: Generic a => a -> Data (Rep a) p
+ Generic.Data.Internal.Generically: instance (GHC.Generics.Generic a, GHC.Base.Semigroup (GHC.Generics.Rep a ())) => GHC.Base.Semigroup (Generic.Data.Internal.Generically.Generically a)
+ Generic.Data.Internal.Meta: type DummyMeta = 'MetaData "" "" "" 'False
+ Generic.Data.Internal.Utils: absurd1 :: V1 x -> a
+ Generic.Data.Internal.Utils: coerce' :: Coercible (f x) (g x) => f x -> g x
+ Generic.Data.Internal.Utils: from' :: Generic a => a -> Rep a ()
+ Generic.Data.Internal.Utils: liftG2 :: Generic1 f => (Rep1 f a -> Rep1 f b -> Rep1 f c) -> f a -> f b -> f c
+ Generic.Data.Internal.Utils: to' :: Generic a => Rep a () -> a
+ Generic.Data.Types: fromData :: Generic a => Data (Rep a) p -> a
+ Generic.Data.Types: toData :: Generic a => a -> Data (Rep a) p
Files
- CHANGELOG.md +6/−0
- README.md +11/−7
- generic-data.cabal +4/−3
- orphans/Generic/Data/Orphans.hs +1/−36
- src/Generic/Data/Internal/Compat.hs +17/−1
- src/Generic/Data/Internal/Data.hs +12/−4
- src/Generic/Data/Internal/Defun.hs +0/−38
- src/Generic/Data/Internal/Functions.hs +0/−11
- src/Generic/Data/Internal/Meta.hs +7/−0
- src/Generic/Data/Internal/Prelude.hs +2/−14
- src/Generic/Data/Internal/Utils.hs +28/−0
- src/Generic/Data/Types.hs +2/−11
- test/unit.hs +9/−1
CHANGELOG.md view
@@ -1,3 +1,9 @@+# 0.2.0.0++- Remove `Generic.Data.Types.Map`+- Add `Generic.Data.Data.Types.toData` and `fromData`+- Remove `Defun` module (subsumed by `first-class-families` package)+ # 0.1.1.0 - Add `gconIndex`
README.md view
@@ -1,4 +1,4 @@-# Generic data types in Haskell [](https://travis-ci.org/Lysxia/generic-data)+# Generic data types in Haskell [](https://hackage.haskell.org/package/generic-data) [](https://travis-ci.org/Lysxia/generic-data) Utilities for `GHC.Generics`. @@ -13,6 +13,8 @@ - `Eq`, `Ord`, `Enum`, `Bounded`, `Show` (standard); - `Functor`, `Foldable`, `Traversable` (via extensions, `DeriveFunctor`, etc.). +(`Read` is currently not implemented.)+ To derive type classes defined elsewhere, it might be worth taking a look at [one-liner](https://hackage.haskell.org/package/one-liner). @@ -24,13 +26,13 @@ ## Related links -generic-data aims to subsume the following packages, which may still be-useful for old versions of GHC and base not supported by generic-data.+generic-data aims to subsume generic deriving features of the following+packages: - [semigroups](https://hackage.haskell.org/package/semigroups): generic- `Semigroup`, `Monoid`.+ `Semigroup`, `Monoid`, but with a heavy dependency footprint. - [transformers-compat](https://hackage.haskell.org/package/transformers-compat):- generic `Eq1`, `Ord1`, `Show1`, `Read1`.+ generic `Eq1`, `Ord1`, `Show1`. - [generic-deriving](https://hackage.haskell.org/package/generic-deriving): doesn't derive the classes in base (defines clones of these classes as a toy example); has Template Haskell code to derive `Generic`.@@ -43,8 +45,10 @@ to using `GHC.Generics` to derive instances of many type classes, including but not restricted to the above classes (this is done in [one-liner-instances](https://hackage.haskell.org/package/one-liner-instances)).-- [singletons](https://hackage.haskell.org/package/singletons):- generic-data borrows code from this package to implement defunctionalization.+- [singletons](https://hackage.haskell.org/package/singletons),+ [first-class-families](https://hackage.haskell.org/package/first-class-families)+ (second one written by me)+ libraries for dependently-typed programming in Haskell. ---
generic-data.cabal view
@@ -1,5 +1,5 @@ name: generic-data-version: 0.1.1.0+version: 0.2.0.0 synopsis: Utilities for GHC.Generics description: This package provides common functions on generic types. See README.@@ -13,7 +13,7 @@ build-type: Simple extra-source-files: README.md, CHANGELOG.md cabal-version: >=1.10-tested-with: GHC == 8.0.2, GHC == 8.2.2+tested-with: GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.3, GHC == 8.6.1 library hs-source-dirs: src@@ -22,7 +22,6 @@ Generic.Data.Types Generic.Data.Internal.Compat Generic.Data.Internal.Data- Generic.Data.Internal.Defun Generic.Data.Internal.Enum Generic.Data.Internal.Functions Generic.Data.Internal.Generically@@ -31,7 +30,9 @@ Generic.Data.Internal.Prelude Generic.Data.Internal.Resolvers Generic.Data.Internal.Show+ Generic.Data.Internal.Utils build-depends:+ base-orphans >= 0.8, contravariant, show-combinators, base >= 4.9 && < 5
orphans/Generic/Data/Orphans.hs view
@@ -8,44 +8,9 @@ module Generic.Data.Orphans where import Data.Functor.Classes+import Data.Orphans () import Data.Semigroup import GHC.Generics--instance Monoid c => Applicative (K1 i c) where- pure _ = K1 mempty- K1 a <*> K1 b = K1 (mempty a b)--instance Semigroup (V1 p) where- v <> _ = v--instance Semigroup (U1 p) where- _ <> _ = U1--instance Monoid (U1 p) where- mempty = U1- mappend = (<>)--deriving instance Semigroup c => Semigroup (K1 i c p)-deriving instance Monoid c => Monoid (K1 i c p)--deriving instance Semigroup (f p) => Semigroup (M1 i c f p)-deriving instance Monoid (f p) => Monoid (M1 i c f p)--instance (Semigroup (f p), Semigroup (g p)) => Semigroup ((f :*: g) p) where- (x1 :*: y1) <> (x2 :*: y2) = (x1 <> x2) :*: (y1 <> y2)--instance (Monoid (f p), Monoid (g p)) => Monoid ((f :*: g) p) where- mempty = mempty :*: mempty- mappend (x1 :*: y1) (x2 :*: y2) = mappend x1 x2 :*: mappend y1 y2--deriving instance Semigroup p => Semigroup (Par1 p)-deriving instance Monoid p => Monoid (Par1 p)--deriving instance Semigroup (f p) => Semigroup (Rec1 f p)-deriving instance Monoid (f p) => Monoid (Rec1 f p)--deriving instance Semigroup (f (g p)) => Semigroup ((f :.: g) p)-deriving instance Monoid (f (g p)) => Monoid ((f :.: g) p) instance Eq1 V1 where liftEq _ v _ = case v of {}
src/Generic/Data/Internal/Compat.hs view
@@ -1,10 +1,17 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE+ CPP,+ DataKinds,+ TypeFamilies,+ TypeOperators,+ UndecidableInstances #-} module Generic.Data.Internal.Compat ( readPrec1+ , Div ) where import Data.Functor.Classes+import GHC.TypeLits #if !MIN_VERSION_base(4,10,0) import Text.ParserCombinators.ReadPrec (ReadPrec, readS_to_Prec)@@ -14,4 +21,13 @@ #if !MIN_VERSION_base(4,10,0) readPrec1 :: (Read1 f, Read a) => ReadPrec (f a) readPrec1 = readS_to_Prec $ liftReadsPrec readsPrec readList+#endif++#if !MIN_VERSION_base(4,11,0)+type Div m n = Div' (CmpNat m n) m n++type family Div' (ord :: Ordering) (m :: Nat) (n :: Nat) :: Nat+type instance Div' 'LT m n = 0+type instance Div' 'GT m n = 1 + Div (m-n) n+type instance Div' 'EQ m n = 1 #endif
src/Generic/Data/Internal/Data.hs view
@@ -20,15 +20,23 @@ import Generic.Data.Internal.Enum import Generic.Data.Internal.Show --- | A wrapper to view a generic 'Rep' as the datatype it's supposed--- to represent, without needing a declaration.+-- | Synthetic data type. ----- This can be used to derive types from generic types, and get some instances--- for free, in particular 'Generic', 'Show', 'Enum', 'Bounded'.+-- A wrapper to view a generic 'Rep' as the datatype it's supposed to+-- represent, without needing a declaration. newtype Data r p = Data { unData :: r p } deriving ( Functor, Foldable, Traversable, Applicative, Alternative , Monad, MonadPlus, Contravariant , Eq, Ord, Eq1, Ord1, Semigroup, Monoid )++-- | Conversion between a generic type and the synthetic type made using its+-- representation.+toData :: Generic a => a -> Data (Rep a) p+toData = Data . from++-- | Inverse of 'fromData'.+fromData :: Generic a => Data (Rep a) p -> a+fromData = to . unData instance (Functor r, Contravariant r) => Generic (Data r p) where type Rep (Data r p) = r
− src/Generic/Data/Internal/Defun.hs
@@ -1,38 +0,0 @@-{- | Defunctionalization--See https://hackage.haskell.org/package/singletons-2.4.1/docs/src/Data-Singletons-Internal.html#TyFun--A copy of the defunctionalization implementation in the singletons package, to-not pull in too heavy dependencies.---}--{-# LANGUAGE DataKinds #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}--module Generic.Data.Internal.Defun where--import Data.Kind--data TyFun :: Type -> Type -> Type---- | Kind of function symbols-type a ~> b = TyFun a b -> Type-infixr 0 ~>--type family (f :: TyFun k1 k2 -> Type) @@ (x :: k1) :: k2-infixl 9 @@---- | Type constructor function symbol-data TyCon :: (k1 -> k2) -> TyFun k1 k2 -> Type-type instance TyCon f @@ x = f x---- | Identity function symbol-data Id :: TyFun k1 k2 -> Type-type instance Id @@ x = x---- | Constant function symbol-data Const :: k2 -> TyFun k1 k2 -> Type-type instance Const t @@ x = t
src/Generic/Data/Internal/Functions.hs view
@@ -17,17 +17,6 @@ import GHC.Generics import GHC.TypeLits -import Generic.Data.Internal.Defun---- | Apply a type function on every field of a type.-type family Map (s :: TyFun a b -> Type) (r :: k -> Type) :: k -> Type-type instance Map s (M1 i c f) = M1 i c (Map s f)-type instance Map s (f :+: g) = Map s f :+: Map s g-type instance Map s (f :*: g) = Map s f :*: Map s g-type instance Map s (K1 i c) = K1 i (s @@ c)-type instance Map s U1 = U1-type instance Map s V1 = V1- -- | Number of constructors of a data type. type family NConstructors (r :: k -> Type) :: Nat type instance NConstructors (M1 D c f) = NConstructors f
src/Generic/Data/Internal/Meta.hs view
@@ -264,3 +264,10 @@ -- | Inferred strictness of a field ('MetaSel'). type family MetaSelStrictness (m :: Meta) :: DecidedStrictness where MetaSelStrictness ('MetaSel _mn _su _ss ds) = ds++-- | A placeholder for 'Meta' values.+type DummyMeta = 'MetaData "" "" "" 'False++-- | Remove an 'M1' type constructor.+type family UnM1 (f :: k -> *) :: k -> *+type instance UnM1 (M1 i c f) = f
src/Generic/Data/Internal/Prelude.hs view
@@ -10,6 +10,8 @@ import Data.Semigroup import GHC.Generics +import Generic.Data.Internal.Utils (from', to', liftG2)+ -- * 'Eq' -- | Generic @('==')@.@@ -184,17 +186,3 @@ :: (Generic1 f, Ord1 (Rep1 f)) => (a -> b -> Ordering) -> f a -> f b -> Ordering gliftCompare = \compare' a b -> liftCompare compare' (from1 a) (from1 b)---- * Utils---- | A helper for better type inference.-from' :: Generic a => a -> Rep a ()-from' = from---- | A helper for better type inference.-to' :: Generic a => Rep a () -> a-to' = to---- | Lift binary combinators generically.-liftG2 :: Generic1 f => (Rep1 f a -> Rep1 f b -> Rep1 f c) -> f a -> f b -> f c-liftG2 = \(<?>) a b -> to1 (from1 a <?> from1 b)
+ src/Generic/Data/Internal/Utils.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE+ BangPatterns,+ PolyKinds #-}++module Generic.Data.Internal.Utils where++import Data.Coerce+import GHC.Generics++-- | Coerce while preserving the type index.+coerce' :: Coercible (f x) (g x) => f x -> g x+coerce' = coerce++-- | Elimination of @V1@.+absurd1 :: V1 x -> a+absurd1 !_ = error "impossible"++-- | A helper for better type inference.+from' :: Generic a => a -> Rep a ()+from' = from++-- | A helper for better type inference.+to' :: Generic a => Rep a () -> a+to' = to++-- | Lift binary combinators generically.+liftG2 :: Generic1 f => (Rep1 f a -> Rep1 f b -> Rep1 f c) -> f a -> f b -> f c+liftG2 = \(<?>) a b -> to1 (from1 a <?> from1 b)
src/Generic/Data/Types.hs view
@@ -4,17 +4,8 @@ module Generic.Data.Types ( Data(..)- , Map-- -- * Defunctionalization- , TyFun- , type (~>)- , type (@@)- , Id- , TyCon- , Const+ , toData+ , fromData ) where import Generic.Data.Internal.Data-import Generic.Data.Internal.Defun-import Generic.Data.Internal.Functions
test/unit.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TypeApplications #-} @@ -42,6 +43,13 @@ data E = E0 | E1 | E2 deriving (Eq, Show, Generic) +maybeModuleName :: String+#if MIN_VERSION_base(4,12,0)+maybeModuleName = "GHC.Maybe"+#else+maybeModuleName = "GHC.Base"+#endif+ main :: IO () main = defaultMain test @@ -100,7 +108,7 @@ , testGroup "Meta" [ testCase "datatypeName" $ "Maybe" @?= gdatatypeName @(Maybe Int)- , testCase "moduleName" $ "GHC.Base" @?= gmoduleName @(Maybe Int)+ , testCase "moduleName" $ maybeModuleName @?= gmoduleName @(Maybe Int) , testCase "packageName" $ "base" @?= gpackageName @(Maybe Int) , testCase "isNewtype" $ False @?= gisNewtype @(Maybe Int) , testCase "conName" $ "Just" @?= gconName (Just ())