invariant 0.5 → 0.5.1
raw patch · 4 files changed
+62/−45 lines, 4 filesdep ~QuickCheckPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: QuickCheck
API changes (from Hackage documentation)
Files
- CHANGELOG.md +4/−0
- invariant.cabal +9/−6
- src/Data/Functor/Invariant/TH.hs +49/−38
- test/InvariantSpec.hs +0/−1
CHANGELOG.md view
@@ -1,3 +1,7 @@+# 0.5.1 [2018.07.15]+* Depend on `QuickCheck-2.11` or later in the test suite.+* Some Haddock fixes in `Data.Functor.Invariant.TH`.+ # 0.5 [2017.12.07] * `Data.Functor.Invariant.TH` now derives `invmap(2)` implementations for empty data types that are strict in the argument.
invariant.cabal view
@@ -1,5 +1,5 @@ name: invariant-version: 0.5+version: 0.5.1 synopsis: Haskell98 invariant functors description: Haskell98 invariant functors (also known as exponential functors). .@@ -24,6 +24,8 @@ , GHC == 7.10.3 , GHC == 8.0.2 , GHC == 8.2.2+ , GHC == 8.4.3+ , GHC == 8.6.1 extra-source-files: CHANGELOG.md, README.md source-repository head@@ -40,7 +42,7 @@ , base >= 4 && < 5 , bifunctors >= 5.2 && < 6 , comonad >= 5 && < 6- , containers >= 0.1 && < 0.6+ , containers >= 0.1 && < 0.7 , contravariant >= 0.5 && < 2 , ghc-prim , profunctors >= 5.2.1 && < 6@@ -48,7 +50,7 @@ , StateVar >= 1.1 && < 2 , stm >= 2.2 && < 3 , tagged >= 0.7.3 && < 1- , template-haskell >= 2.4 && < 2.13+ , template-haskell >= 2.4 && < 2.15 , th-abstraction >= 0.2.2 && < 1 , transformers >= 0.2 && < 0.6 , transformers-compat >= 0.3 && < 1@@ -61,9 +63,10 @@ main-is: Spec.hs other-modules: InvariantSpec THSpec- build-depends: base >= 4 && < 5+ build-depends: base >= 4 && < 5 , hspec >= 1.8 , invariant- , QuickCheck >= 2 && < 3- , template-haskell >= 2.4 && < 2.13+ , QuickCheck >= 2.11 && < 3+ , template-haskell >= 2.4 && < 2.15+ build-tool-depends: hspec-discover:hspec-discover ghc-options: -Wall
src/Data/Functor/Invariant/TH.hs view
@@ -7,8 +7,10 @@ Maintainer: Ryan Scott Portability: Template Haskell -Functions to mechanically derive 'Invariant' or 'Invariant2' instances,-or to splice 'invmap' or 'invmap2' into Haskell source code. You need to enable+Functions to mechanically derive 'Data.Functor.Invariant.Invariant'+or 'Data.Functor.Invariant.Invariant2' instances,+or to splice 'Data.Functor.Invariant.invmap' or+'Data.Functor.Invariant.invmap2' into Haskell source code. You need to enable the @TemplateHaskell@ language extension in order to use this module. -} module Data.Functor.Invariant.TH (@@ -64,10 +66,11 @@ {- $deriveInvariant -'deriveInvariant' automatically generates an 'Invariant' instance declaration for a-data type, newtype, or data family instance that has at least one type variable.-This emulates what would (hypothetically) happen if you could attach a @deriving-'Invariant'@ clause to the end of a data declaration. Examples:+'deriveInvariant' automatically generates an 'Data.Functor.Invariant.Invariant'+instance declaration for a data type, newtype, or data family instance that has+at least one type variable. This emulates what would (hypothetically) happen+if you could attach a @deriving 'Data.Functor.Invariant.Invariant'@ clause to+the end of a data declaration. Examples: @ {-# LANGUAGE TemplateHaskell #-}@@ -81,7 +84,7 @@ @ If you are using @template-haskell-2.7.0.0@ or later (i.e., GHC 7.4 or later),-'deriveInvariant' can also be used to derive 'Invariant' instances for data family+'deriveInvariant' can also be used to derive 'Data.Functor.Invariant.Invariant' instances for data family instances (which requires the @-XTypeFamilies@ extension). To do so, pass the name of a data or newtype instance constructor to 'deriveInvariant'. Note that the generated code may require the @-XFlexibleInstances@ extension. Some examples:@@ -107,18 +110,19 @@ * The 'Name' argument to 'deriveInvariant' must not be a type synonym. * With 'deriveInvariant', the argument's last type variable must be of kind @*@.- For other ones, type variables of kind @* -> *@ are assumed to require an 'Invariant'- context. For more complicated scenarios, use 'makeInvmap'.+ For other ones, type variables of kind @* -> *@ are assumed to require an+ 'Data.Functor.Invariant.Invariant' context. For more complicated scenarios,+ use 'makeInvmap'. * If using the @-XDatatypeContexts@, @-XExistentialQuantification@, or @-XGADTs@ extensions, a constraint cannot mention the last type variable. For example, @data Illegal a where I :: Ord a => a -> Illegal a@ cannot have a derived- 'Invariant' instance.+ 'Data.Functor.Invariant.Invariant' instance. * If the last type variable is used within a data field of a constructor, it must only be used in the last argument of the data type constructor. For example, @data Legal a- = Legal (Either Int a)@ can have a derived 'Invariant' instance, but @data Illegal a =- Illegal (Either a a)@ cannot.+ = Legal (Either Int a)@ can have a derived 'Data.Functor.Invariant.Invariant' instance,+ but @data Illegal a = Illegal (Either a a)@ cannot. * Data family instances must be able to eta-reduce the last type variable. In other words, if you have a instance of the form:@@ -135,8 +139,8 @@ -} --- | Generates an 'Invariant' instance declaration for the given data type or data--- family instance.+-- | Generates an 'Data.Functor.Invariant.Invariant' instance declaration for the given+-- data type or data family instance. deriveInvariant :: Name -> Q [Dec] deriveInvariant = deriveInvariantOptions defaultOptions @@ -146,10 +150,12 @@ {- $deriveInvariant2 -'deriveInvariant2' automatically generates an 'Invariant2' instance declaration for-a data type, newtype, or data family instance that has at least two type variables.-This emulates what would (hypothetically) happen if you could attach a @deriving-'Invariant2'@ clause to the end of a data declaration. Examples:+'deriveInvariant2' automatically generates an+'Data.Functor.Invariant.Invariant2' instance declaration for a data type,+newtype, or data family instance that has at least two type variables. This+emulates what would (hypothetically) happen if you could attach a @deriving+'Data.Functor.Invariant.Invariant2'@ clause to the end of a data declaration.+Examples: @ {-# LANGUAGE TemplateHaskell #-}@@ -166,19 +172,20 @@ with some caveats: * With 'deriveInvariant2', the last type variables must both be of kind @*@. For other- ones, type variables of kind @* -> *@ are assumed to require an 'Invariant'+ ones, type variables of kind @* -> *@ are assumed to require an 'Data.Functor.Invariant.Invariant' constraint, and type variables of kind @* -> * -> *@ are assumed to require an- 'Invariant2' constraint. For more complicated scenarios, use 'makeInvmap2'.+ 'Data.Functor.Invariant.Invariant2' constraint. For more complicated scenarios, use 'makeInvmap2'. * If using the @-XDatatypeContexts@, @-XExistentialQuantification@, or @-XGADTs@ extensions, a constraint cannot mention either of the last two type variables. For example, @data Illegal2 a b where I2 :: Ord a => a -> b -> Illegal2 a b@ cannot- have a derived 'Invariant2' instance.+ have a derived 'Data.Functor.Invariant.Invariant2' instance. * If either of the last two type variables is used within a data field of a constructor, it must only be used in the last two arguments of the data type constructor. For- example, @data Legal a b = Legal (Int, Int, a, b)@ can have a derived 'Invariant2'- instance, but @data Illegal a b = Illegal (a, b, a, b)@ cannot.+ example, @data Legal a b = Legal (Int, Int, a, b)@ can have a derived+ 'Data.Functor.Invariant.Invariant2' instance, but+ @data Illegal a b = Illegal (a, b, a, b)@ cannot. * Data family instances must be able to eta-reduce the last two type variables. In other words, if you have a instance of the form:@@ -195,8 +202,8 @@ -} --- | Generates an 'Invariant2' instance declaration for the given data type or data--- family instance.+-- | Generates an 'Data.Functor.Invariant.Invariant2' instance declaration for+-- the given data type or data family instance. deriveInvariant2 :: Name -> Q [Dec] deriveInvariant2 = deriveInvariant2Options defaultOptions @@ -206,16 +213,18 @@ {- $make -There may be scenarios in which you want to @invmap@ over an arbitrary data type or-data family instance without having to make the type an instance of 'Invariant'. For-these cases, this module provides several functions (all prefixed with @make-@) that-splice the appropriate lambda expression into your source code. Example:+There may be scenarios in which you want to @invmap@ over an arbitrary data+type or data family instance without having to make the type an instance of+'Data.Functor.Invariant.Invariant'. For these cases, this module provides+several functions (all prefixed with @make-@) that splice the appropriate+lambda expression into your source code. Example: -This is particularly useful for creating instances for sophisticated data types. For-example, 'deriveInvariant' cannot infer the correct type context for @newtype-HigherKinded f a b c = HigherKinded (f a b c)@, since @f@ is of kind-@* -> * -> * -> *@. However, it is still possible to create an 'Invariant' instance-for @HigherKinded@ without too much trouble using 'makeInvmap':+This is particularly useful for creating instances for sophisticated data+types. For example, 'deriveInvariant' cannot infer the correct type context for+@newtype HigherKinded f a b c = HigherKinded (f a b c)@, since @f@ is of kind+@* -> * -> * -> *@. However, it is still possible to create an+'Data.Functor.Invariant.Invariant' instance for @HigherKinded@ without too much+trouble using 'makeInvmap': @ {-# LANGUAGE FlexibleContexts, TemplateHaskell #-}@@ -230,8 +239,9 @@ -} --- | Generates a lambda expression which behaves like 'invmap' (without requiring an--- 'Invariant' instance).+-- | Generates a lambda expression which behaves like+-- 'Data.Functor.Invariant.invmap' (without requiring an+-- 'Data.Functor.Invariant.Invariant' instance). makeInvmap :: Name -> Q Exp makeInvmap = makeInvmapOptions defaultOptions @@ -239,8 +249,9 @@ makeInvmapOptions :: Options -> Name -> Q Exp makeInvmapOptions = makeInvmapClass Invariant --- | Generates a lambda expression which behaves like 'invmap2' (without requiring an--- 'Invariant2' instance).+-- | Generates a lambda expression which behaves like+-- 'Data.Functor.Invariant.invmap2' (without requiring an+-- 'Data.Functor.Invariant.Invariant2' instance). makeInvmap2 :: Name -> Q Exp makeInvmap2 = makeInvmap2Options defaultOptions
test/InvariantSpec.hs view
@@ -4,7 +4,6 @@ import Test.Hspec import Test.Hspec.QuickCheck (prop) import Test.QuickCheck-import Test.QuickCheck.Function main :: IO () main = hspec spec