overloaded-records 0.4.1.0 → 0.4.2.0
raw patch · 7 files changed
+1054/−53 lines, 7 filesdep ~data-default-classdep ~transformersPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: data-default-class, transformers
API changes (from Hackage documentation)
- Data.OverloadedLabels: class IsLabel (l :: Symbol) a
- Data.OverloadedLabels: fromLabel :: IsLabel l a => Proxy# l -> a
- Data.OverloadedRecords: Rec :: r -> Rec ts r
- Data.OverloadedRecords: data Modifier s t a b
- Data.OverloadedRecords: instance Data.OverloadedRecords.HasField l s a => Data.OverloadedLabels.IsLabel l (Data.OverloadedRecords.Getter s a)
- Data.OverloadedRecords: instance Data.OverloadedRecords.IsFieldAccessor l x y (Data.OverloadedRecords.FromArrow x) => Data.OverloadedLabels.IsLabel l (x -> y)
- Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField l s t a b => Data.OverloadedLabels.IsLabel l (Data.OverloadedRecords.Modifier s t a b)
- Data.OverloadedRecords: instance GHC.Generics.Constructor Data.OverloadedRecords.C1_0Getter
- Data.OverloadedRecords: instance GHC.Generics.Constructor Data.OverloadedRecords.C1_0Modifier
- Data.OverloadedRecords: instance GHC.Generics.Datatype Data.OverloadedRecords.D1Getter
- Data.OverloadedRecords: instance GHC.Generics.Datatype Data.OverloadedRecords.D1Modifier
- Data.OverloadedRecords.TH: fieldDerivation :: IsLabel "fieldDerivation" a => a
- Data.OverloadedRecords.TH.Internal: fieldDerivation :: IsLabel "fieldDerivation" a => a
- Data.OverloadedRecords.TH.Internal: instance GHC.Generics.Constructor Data.OverloadedRecords.TH.Internal.C1_0DeriveOverloadedRecordsParams
- Data.OverloadedRecords.TH.Internal: instance GHC.Generics.Constructor Data.OverloadedRecords.TH.Internal.C1_0OverloadedField
- Data.OverloadedRecords.TH.Internal: instance GHC.Generics.Constructor Data.OverloadedRecords.TH.Internal.C1_1OverloadedField
- Data.OverloadedRecords.TH.Internal: instance GHC.Generics.Datatype Data.OverloadedRecords.TH.Internal.D1DeriveOverloadedRecordsParams
- Data.OverloadedRecords.TH.Internal: instance GHC.Generics.Datatype Data.OverloadedRecords.TH.Internal.D1OverloadedField
- Data.OverloadedRecords.TH.Internal: instance GHC.Generics.Selector Data.OverloadedRecords.TH.Internal.S1_0_0DeriveOverloadedRecordsParams
- Data.OverloadedRecords.TH.Internal: instance GHC.Generics.Selector Data.OverloadedRecords.TH.Internal.S1_0_1DeriveOverloadedRecordsParams
+ Data.OverloadedLabels: Label :: (Proxy# l) -> Label
+ Data.OverloadedLabels: data Label (l :: Symbol)
+ Data.OverloadedLabels: getLabel :: Label l -> Label l
+ Data.OverloadedLabels: instance GHC.TypeLits.KnownSymbol l => GHC.Show.Show (Data.OverloadedLabels.Label l)
+ Data.OverloadedLabels: instance l1 ~ l2 => GHC.OverloadedLabels.IsLabel l1 (Data.OverloadedLabels.Label l2)
+ Data.OverloadedLabels: showLabel :: KnownSymbol l => Label l -> String
+ Data.OverloadedLabels: unLabel :: IsLabel l a => Label l -> a
+ Data.OverloadedRecords: Modifier :: ((a -> b) -> s -> t) -> Modifier s t a b
+ Data.OverloadedRecords: WrappedLensLike :: ((a -> f b) -> s -> f t) -> WrappedLensLike f s t a b
+ Data.OverloadedRecords: [Rec] :: R ctx r => r -> Rec ctx r
+ Data.OverloadedRecords: class (ModifyRec# l a cs (Position l a cs) (Position l a cs == 0)) => ModifyRec (l :: Symbol) a (cs :: [(Symbol, *)]) where getRecField = getRecField# (proxy# :: Proxy# '(Position l a cs, Position l a cs == 0)) modifyRecField = modifyRecField# (proxy# :: Proxy# '(Position l a cs, Position l a cs == 0)) setRecField = setRecField# (proxy# :: Proxy# '(Position l a cs, Position l a cs == 0))
+ Data.OverloadedRecords: getRecField :: ModifyRec l a cs => Proxy# l -> Rec cs r -> a
+ Data.OverloadedRecords: instance (GHC.Base.Functor f, Data.OverloadedRecords.ModifyField l s t a b) => GHC.OverloadedLabels.IsLabel l (Data.OverloadedRecords.WrappedLensLike f s t a b)
+ Data.OverloadedRecords: instance (cs ~ (l' Data.OverloadedRecords.::: b : cs'), n' ~ (n GHC.TypeLits.- 1), Data.OverloadedRecords.ModifyRec# l a cs' n' (n' Data.Type.Equality.== 0)) => Data.OverloadedRecords.ModifyRec# l a cs n 'GHC.Types.False
+ Data.OverloadedRecords: instance Data.Functor.Classes.Eq1 (Data.OverloadedRecords.Rec ctx)
+ Data.OverloadedRecords: instance Data.Functor.Classes.Ord1 (Data.OverloadedRecords.Rec ctx)
+ Data.OverloadedRecords: instance Data.Functor.Classes.Show1 (Data.OverloadedRecords.Rec ctx)
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "curry" ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) -> r) (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> r)
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "curry" ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) -> r) (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> a12 -> r)
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "curry" ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) -> r) (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> a12 -> a13 -> r)
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "curry" ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) -> r) (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> a12 -> a13 -> a14 -> r)
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "curry" ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) -> r) (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> a12 -> a13 -> a14 -> a15 -> r)
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a1
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a1
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a1
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a1
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a1
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a2
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a2
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a2
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a2
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a2
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a3
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a3
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a3
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a3
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a3
+ Data.OverloadedRecords: instance Data.OverloadedRecords.HasField l s a => GHC.OverloadedLabels.IsLabel l (Data.OverloadedRecords.Getter s a)
+ Data.OverloadedRecords: instance Data.OverloadedRecords.IsFieldAccessor l x y (Data.OverloadedRecords.FromArrow x) => GHC.OverloadedLabels.IsLabel l (x -> y)
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a1 a1'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a1 a1'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a1 a1'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a1 a1'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a1 a1'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11) a2 a2'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a2 a2'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a2 a2'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a2 a2'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a2 a2'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11) a3 a3'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12) a3 a3'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a3 a3'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a3 a3'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a3 a3'
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyField l s t a b => GHC.OverloadedLabels.IsLabel l (Data.OverloadedRecords.Modifier s t a b)
+ Data.OverloadedRecords: instance Data.OverloadedRecords.ModifyRec# l a cs (Data.OverloadedRecords.Position l a cs) (Data.OverloadedRecords.Position l a cs Data.Type.Equality.== 0) => Data.OverloadedRecords.ModifyRec l a cs
+ Data.OverloadedRecords: instance GHC.Classes.Eq r => GHC.Classes.Eq (Data.OverloadedRecords.Rec ctx r)
+ Data.OverloadedRecords: instance GHC.Classes.Ord r => GHC.Classes.Ord (Data.OverloadedRecords.Rec ctx r)
+ Data.OverloadedRecords: instance GHC.Show.Show r => GHC.Show.Show (Data.OverloadedRecords.Rec ctx r)
+ Data.OverloadedRecords: instance cs ~ (l Data.OverloadedRecords.::: a : cs') => Data.OverloadedRecords.ModifyRec# l a cs 0 'GHC.Types.True
+ Data.OverloadedRecords: lns :: WrappedLensLike f s t a b -> (a -> f b) -> s -> f t
+ Data.OverloadedRecords: lns' :: WrappedLensLike' f s a -> (a -> f a) -> s -> f s
+ Data.OverloadedRecords: modifyRecField :: ModifyRec l a cs => Proxy# l -> (a -> a) -> Rec cs r -> Rec cs r
+ Data.OverloadedRecords: newtype Modifier s t a b
+ Data.OverloadedRecords: newtype WrappedLensLike f s t a b
+ Data.OverloadedRecords: setRecField :: ModifyRec l a cs => Proxy# l -> Rec cs r -> a -> Rec cs r
+ Data.OverloadedRecords: strengthenRec :: ModifyField' l r a => Rec ctx r -> Rec ((l ::: a) : ctx) r
+ Data.OverloadedRecords: type WrappedLensLike' f s a = WrappedLensLike f s s a a
+ Data.OverloadedRecords: weakenRec :: Rec ((l ::: a) : ctx) r -> Rec ctx r
- Data.OverloadedRecords: data Rec ts r
+ Data.OverloadedRecords: data Rec ctx r
- Data.OverloadedRecords.TH.Internal: deriveForConstructor :: DeriveOverloadedRecordsParams -> Name -> [TyVarBndr] -> Con -> DecsQ
+ Data.OverloadedRecords.TH.Internal: deriveForConstructor :: DeriveOverloadedRecordsParams -> [(String, String)] -> Name -> [TyVarBndr] -> Con -> (DecsQ, [(String, String)])
- Data.OverloadedRecords.TH.Internal: deriveForField :: DeriveOverloadedRecordsParams -> DeriveFieldParams -> DecsQ
+ Data.OverloadedRecords.TH.Internal: deriveForField :: DeriveOverloadedRecordsParams -> [(String, String)] -> DeriveFieldParams -> (DecsQ, Maybe (String, String))
Files
- ChangeLog.md +27/−0
- README.md +15/−2
- overloaded-records.cabal +25/−10
- src/Data/OverloadedLabels.hs +65/−3
- src/Data/OverloadedRecords.hs +812/−13
- src/Data/OverloadedRecords/TH/Internal.hs +92/−24
- test/TestCase/Data/OverloadedRecords.hs +18/−1
ChangeLog.md view
@@ -1,6 +1,33 @@ # ChangeLog / ReleaseNotes +## Version 0.4.2.0++* `Rec` instances for `Eq1`, `Ord1`, `Show1`, `Eq`, `Ord`, and `Show`.+ Instances for `Eq1`, `Ord1` and `Show1` are available only with transformers+ ==0.5.\* or with base >=4.9 (i.e. GHC >=8). (**new**)+* Introducing `WrappedLensLike` data type along with a simplified type+ `WrappedLensLike'`. For each of these we have corresponding `lns` and `lns'`+ operation for unpacking `WrappedLensLike`. (**new**)+ * `lns :: WrappedLensLike f s t a b -> (a -> f b) -> s -> f t`+ * `lns' :: WrappedLensLike' f s a -> (a -> f a) -> s -> f s`+* Allowing fields\/accessors to occur in multiple data constructors by not+ creating duplicit instances, thanks to+ [Andy Morris](https://github.com/andy-morris). See+ [pull request #2](https://github.com/trskop/overloaded-records/pull/2).+ (**change**)+* Data type `Label (l :: Symbol)` that can be used to pass label value around.+ (**new**)+* Instances for `fst`, `snd`, `thd` and `curry` fields for 11-tuples, 12-tuples+ up to 15-tuples. (**new**)+* Instances for `head` and `tail` fields for `NonEmpty` list. (**new**)+* Instances for `HasField` and `ModifyField` `Rec context r` where `r` is+ monomorphic. This is just a poor man's instance, since its usability is very+ limited, but helpful in those special cases. Hopefully we will be able to+ find a way how to define overloaded records machinery for `Rec context r` in+ general. (**new**)++ ## Version 0.4.1.0 * Introducing `Getter` newtype along with `get` function. (**new**)
README.md view
@@ -50,8 +50,6 @@ add n = bar +~ n ``` -This implementation is highly experimental and may change rapidly.- More about the current status of OverloadedRecordFields language extension can be found on [GHC Wiki: OverloadedRecordFields][]. @@ -193,6 +191,15 @@ afraid to contact author using GitHub or by e-mail. +## Related Work++* [ruin][Hackage: ruin] is a DSL for working with record types that also+ leverages OverloadedLabels language extension.+* [vinyl][Hackage: vinyl] provides extensible records for Haskell with lenses+ using modern GHC features.+++ [GHC Wiki: OverloadedRecordFields]: https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields "OverloadedRecordFields language extension on GHC Wiki"@@ -202,6 +209,12 @@ [Hackage: overloaded-records]: http://hackage.haskell.org/package/overloaded-records "overloaded-records package on Hackage"+[Hackage: ruin]:+ https://hackage.haskell.org/package/ruin+ "ruin package on Hackage"+[Hackage: vinyl]:+ https://hackage.haskell.org/package/vinyl+ "vinyl package on Hackage" [Haskell.org]: http://www.haskell.org "The Haskell Programming Language"
overloaded-records.cabal view
@@ -1,5 +1,5 @@ name: overloaded-records-version: 0.4.1.0+version: 0.4.2.0 synopsis: Overloaded Records based on current GHC proposal. description: Implementation of /Overloaded Record Fields/ based on current GHC proposal.@@ -11,8 +11,6 @@ . See README for usage examples. .- This implementation is highly experimental and may change rapidly.- . More about the current status of OverloadedRecordFields language extension can be found on: <https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields GHC Wiki: OverloadedRecordFields>.@@ -37,6 +35,13 @@ default: False manual: True +flag force-functor-classes+ description:+ Force dependency on transformers ==0.5.* when compiled with GHC <8 to+ define Eq1, Ord1 and Show1 instances for Rec data type.+ default: False+ manual: False+ library hs-source-dirs: src exposed-modules:@@ -71,11 +76,16 @@ build-depends: base >=4.7 && <5- , data-default-class ==0.0.*+ , data-default-class ==0.0.* || ==0.1.* , template-haskell >=2.9 && <2.12 + if impl(ghc <8) && flag(force-functor-classes)+ build-depends: transformers ==0.5.*+ cpp-options: -DHAVE_FUNCTOR_CLASSES+ if impl(ghc >=8.0) cpp-options:+ -DHAVE_FUNCTOR_CLASSES -DHAVE_MONAD_FAIL -DHAVE_OVERLOADED_LABELS -- -DHAVE_TYPE_FAMILY_DEPENDENCIES@@ -139,15 +149,20 @@ , overloaded-records - if impl(ghc <7.10)- -- Identity functor is available in base bundled with GHC >=7.10, for older- -- we need to get it elsewhere.- build-depends:- transformers >=0.2+ if impl(ghc <8) && flag(force-functor-classes)+ build-depends: transformers ==0.5.*+ cpp-options: -DHAVE_FUNCTOR_CLASSES+ else+ if impl(ghc <7.10)+ -- Identity functor is available in base bundled with GHC >=7.10, for+ -- older we need to get it elsewhere.+ build-depends: transformers >=0.2 if impl(ghc >=8.0) cpp-options:+ -DHAVE_FUNCTOR_CLASSES -DHAVE_MONAD_FAIL+ -DHAVE_NON_EMPTY_LIST -DHAVE_OVERLOADED_LABELS -- -DHAVE_TYPE_FAMILY_DEPENDENCIES @@ -165,4 +180,4 @@ source-repository this type: git location: git://github.com/trskop/overloaded-records.git- tag: 0.4.1.0+ tag: 0.4.2.0
src/Data/OverloadedLabels.hs view
@@ -1,10 +1,12 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE TypeFamilies #-} -- For type equality constraint. -- | -- Module: $HEADER$ -- Description: Magic class for OverloadedLabels.@@ -13,7 +15,7 @@ -- -- Maintainer: peter.trsko@gmail.com -- Stability: experimental--- Portability: NoImplicitPrelude+-- Portability: GHC specific language extensions. -- -- This module defines the `IsLabel` class which is used by the OverloadedLabels -- language extension. See the@@ -36,16 +38,76 @@ #else IsLabel(..) #endif++ , Label(..)+ , getLabel+ , showLabel+ , unLabel ) where +import Data.Function ((.), id)+import Data.String (String)+import Data.Typeable (Typeable)+import GHC.TypeLits+ ( KnownSymbol+ , Symbol+#if MIN_VERSION_base(4,8,0)+ , symbolVal'+#else+ , symbolVal+#endif+ )+import GHC.Exts (Proxy#)+import Text.Show (Show(show, showsPrec), showChar, showString)+ #ifdef HAVE_OVERLOADED_LABELS import GHC.OverloadedLabels #else-import GHC.TypeLits (Symbol)-import GHC.Exts (Proxy#) class IsLabel (l :: Symbol) a where fromLabel :: Proxy# l -> a #endif++-- |+-- /Since 0.4.2.0/+data Label (l :: Symbol) = Label (Proxy# l)+ deriving Typeable++-- |+-- /Since 0.4.2.0/+instance KnownSymbol l => Show (Label l) where+ showsPrec _ l = showChar '#' . showString (showLabel' l)+ where+#if MIN_VERSION_base(4,8,0)+ showLabel' (Label p) = symbolVal' p+#else+ showLabel' = symbolVal+#endif++-- |+-- /Since 0.4.2.0/+instance (l1 ~ l2) => IsLabel l1 (Label l2) where+ fromLabel = Label++-- | Type restricted version of 'show'.+--+-- >>> showLabel #foo+-- #foo+--+-- /Since 0.4.2.0/+showLabel :: KnownSymbol l => Label l -> String+showLabel = show++-- | Type restricted identity function.+--+-- /Since 0.4.2.0/+getLabel :: Label l -> Label l+getLabel = id++-- | Same as 'fromLabel', but works for 'Label' data type.+--+-- /Since 0.4.2.0/+unLabel :: IsLabel l a => Label l -> a+unLabel (Label proxy) = fromLabel proxy
src/Data/OverloadedRecords.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-}@@ -11,10 +12,19 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-}++#ifndef HAVE_FUNCTOR_CLASSES+-- With Data.Functor.Classes available, we use Eq1, Ord1 and Show1 to define+-- Eq, Ord and Show. When it is not available then we can use standalone+-- deriving to get them derived for us.+{-# LANGUAGE StandaloneDeriving #-}+#endif+ -- | -- Module: $HEADER$ -- Description: Magic classes for OverloadedRecordFields.@@ -23,11 +33,7 @@ -- -- Maintainer: peter.trsko@gmail.com -- Stability: experimental--- Portability: ConstraintKinds, DataKinds, DeriveDataTypeable, DeriveGeneric,--- FlexibleInstances, FlexibleContexts, FunctionalDependencies,--- GADTs, LambdaCase, MagicHash, MultiParamTypeClasses,--- NoImplicitPrelude, RankNTypes, TypeFamilies, TypeOperators,--- UndecidableInstances+-- Portability: GHC specific language extensions. -- -- Magic classes for OverloadedRecordFields. --@@ -52,10 +58,11 @@ , Getter , get - -- ** Setter and Modifier+ -- ** Setter, Modifier and Lens , UpdateType , ModifyField(..) , R+ , Rs , (:::) , Rec(..) @@ -65,10 +72,18 @@ , Setter , set - , Modifier+ , Modifier(..) , modify - -- ** Simple Setter and Modifier+ , WrappedLensLike(..)+ , lns++ , ModifyRec(..)+ , weakenRec+ , strengthenRec+ , Position++ -- ** Simple Setter, Modifier and Lens , ModifyField' , fieldLens' , modifyField'@@ -80,6 +95,9 @@ , Modifier' , modify' + , WrappedLensLike'+ , lns'+ -- ** IsLabel For Getter and Lens , FromArrow , IsFieldAccessor(..)@@ -87,15 +105,40 @@ where import Data.Bool (Bool(False, True))-import Data.Function (const)+import Data.Function (($), const) import Data.Functor (Functor, (<$>)) import Data.Maybe (Maybe(Just, Nothing)) import Data.Proxy (Proxy)+import Data.Type.Equality (type (==)) import Data.Typeable (Typeable)-import GHC.Exts (Constraint, Proxy#)+import GHC.Exts (Constraint, Proxy#, proxy#) import GHC.Generics (Generic, Generic1)-import GHC.TypeLits (Symbol)+import GHC.TypeLits (type (-), type (+), Nat, Symbol) +#ifdef HAVE_FUNCTOR_CLASSES+import Data.Eq (Eq((==)))+import Data.Functor.Classes+ ( Eq1(liftEq)+ , Ord1(liftCompare)+ , Show1(liftShowsPrec)+ , compare1+ , eq1+ , showsPrec1+ , showsUnaryWith+ )+import Data.Ord (Ord(compare))+import Text.Show (Show(showsPrec))+#else+-- Will use StandaloneDeriving to derive instances for these.+import Data.Eq (Eq)+import Data.Ord (Ord)+import Text.Show (Show)+#endif++#ifdef HAVE_NON_EMPTY_LIST+import Data.List.NonEmpty (NonEmpty((:|)))+#endif+ import Data.OverloadedLabels @@ -239,6 +282,13 @@ R '[] r = () R ('(l, a) ': ts) r = (ModifyField' l r a, R ts r) +-- | Union\/concatenation of record constraints.+--+-- /Since 0.4.2.0/+type family Rs (cs :: [[(Symbol, *)]]) (r :: *) where+ Rs '[] r = R '[] r+ Rs (c ': cs) r = (R c r, Rs cs r)+ -- | This type alias is used for more readable type signatures when using 'R' -- type family. --@@ -271,11 +321,126 @@ -- >>> zeroV3 (V3 1 1 1 :: V3 Int) -- V3 {_x = 0, _y = 0, _z = 0} --+-- Difference between using a constraint, via 'R' type family, and using 'Rec',+-- is that 'Rec' retains run-time proof that the record has a specified fields.+-- More about this distinction can be found for example in+-- /Hasochism: The Pleasure and Pain of Dependently Typed Haskell Programming/+-- by /Sam Lindley/ and /Conor McBride/ available on-line+-- <https://personal.cis.strath.ac.uk/conor.mcbride/pub/hasochism.pdf>.+-- -- /Since 0.4.1.0/-data Rec ts r where- Rec :: R ts r => r -> Rec ts r+data Rec ctx r where+ Rec :: R ctx r => r -> Rec ctx r deriving (Typeable) +-- | Weakening a record constraint.+weakenRec :: Rec ((l ::: a) ': ctx) r -> Rec ctx r+weakenRec (Rec r) = Rec r++-- | Strengthening a record constraint.+strengthenRec :: ModifyField' l r a => Rec ctx r -> Rec ((l ::: a) ': ctx) r+strengthenRec (Rec r) = Rec r++#ifdef HAVE_FUNCTOR_CLASSES+instance Eq1 (Rec ctx) where+ -- :: (a -> b -> Bool) -> f a -> f b -> Bool+ liftEq f (Rec a) (Rec b) = f a b++instance Ord1 (Rec ctx) where+ -- :: (a -> b -> Ordering) -> f a -> f b -> Ordering+ liftCompare f (Rec a) (Rec b) = f a b++instance Show1 (Rec ctx) where+ -- :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> f a -> ShowS+ liftShowsPrec sp _sl d (Rec r) = showsUnaryWith sp "Rec" d r++instance Eq r => Eq (Rec ctx r) where+ (==) = eq1++instance Ord r => Ord (Rec ctx r) where+ compare = compare1++instance Show r => Show (Rec ctx r) where+ showsPrec = showsPrec1+#else+deriving instance Eq r => Eq (Rec ctx r)+deriving instance Ord r => Ord (Rec ctx r)+deriving instance Show r => Show (Rec ctx r)+#endif++-- | Internal implementation of 'ModifyRec' type class. There should be no need+-- to use it directly or to add an instance to it.+class ModifyRec# (l :: Symbol) a (cs :: [(Symbol, *)]) (n :: Nat) (b :: Bool)+ where+ getRecField# :: Proxy# '(n, b) -> Proxy# l -> Rec cs r -> a++ modifyRecField#+ :: Proxy# '(n, b) -> Proxy# l -> (a -> a) -> Rec cs r -> Rec cs r++ setRecField# :: Proxy# '(n, b) -> Proxy# l -> Rec cs r -> a -> Rec cs r++ -- TODO:+ --+ -- Find a way how to do type changing modification and assignment:+ --+ -- modifyRecField#+ -- :: Proxy# '(n, nb) -> Proxy# l -> (a -> b) -> Rec cs r -> Rec cs s+ --+ -- setRecField#+ -- :: Proxy# '(n, nb) -> Proxy# l -> Rec cs r -> b -> Rec cs s+ --+ -- This would probably require to construct new record constraint with the+ -- member (l, a) changed to (l, b).++instance (cs ~ ((l ::: a) ': cs')) => ModifyRec# l a cs 0 'True where+ getRecField# _ p (Rec r) = getField p r+ modifyRecField# _ p f (Rec r) = Rec (modifyField p f r)+ setRecField# _ p (Rec r) a = Rec (setField p r a)++instance+ ( cs ~ ((l' ::: b) ': cs')+ , n' ~ (n - 1)+ , ModifyRec# l a cs' n' (n' == 0)+ ) => ModifyRec# l a cs n 'False+ where+ getRecField# _ p r =+ getRecField# (proxy# :: Proxy# '(n', n' == 0)) p (weakenRec r)++ modifyRecField# _ p f r@(Rec _) = strengthenRec+ $ modifyRecField# (proxy# :: Proxy# '(n', n' == 0)) p f (weakenRec r)++ setRecField# _ p r@(Rec _) a = strengthenRec+ $ setRecField# (proxy# :: Proxy# '(n', n' == 0)) p (weakenRec r) a++-- | Calculate position of @(l :: Symbol, a :: *)@ in type level list @(cs ::+-- [(Symbol, *)])@. It is used to move through type level list via the type+-- class instance chain until the correct element is reached.+type family Position (l :: Symbol) (a :: *) (cs :: [(Symbol, *)]) :: Nat where+ Position l a ('(l, a) ': cs) = 0+ Position l a (any ': cs) = 1 + Position l a cs++-- | This type class provides functionality as 'HasField' and 'ModifyField',+-- but for overloaded records wrapped in 'Rec' type.+class+ ( ModifyRec# l a cs (Position l a cs) (Position l a cs == 0)+ ) => ModifyRec (l :: Symbol) a (cs :: [(Symbol, *)])+ where+ getRecField :: Proxy# l -> Rec cs r -> a+ getRecField = getRecField#+ (proxy# :: Proxy# '(Position l a cs, Position l a cs == 0))++ modifyRecField :: Proxy# l -> (a -> a) -> Rec cs r -> Rec cs r+ modifyRecField = modifyRecField#+ (proxy# :: Proxy# '(Position l a cs, Position l a cs == 0))++ setRecField :: Proxy# l -> Rec cs r -> a -> Rec cs r+ setRecField = setRecField#+ (proxy# :: Proxy# '(Position l a cs, Position l a cs == 0))++instance+ ( ModifyRec# l a cs (Position l a cs) (Position l a cs == 0)+ ) => ModifyRec l a cs+ -- {{{ Getter ----------------------------------------------------------------- -- | Provides alternative to the \"native\" 'IsLabel' instance for getter.@@ -434,10 +599,40 @@ -- }}} Modifier --------------------------------------------------------------- +-- {{{ Lens -------------------------------------------------------------------++-- | /Since 0.4.2.0/+newtype WrappedLensLike f s t a b = WrappedLensLike ((a -> f b) -> s -> f t)++-- | /Since 0.4.2.0/+instance+ ( Functor f+ , ModifyField l s t a b+ ) => IsLabel l (WrappedLensLike f s t a b)+ where+ fromLabel proxy = WrappedLensLike (fieldLens proxy)++-- | /Since 0.4.2.0/+type WrappedLensLike' f s a = WrappedLensLike f s s a a++-- | /Since 0.4.2.0/+lns :: WrappedLensLike f s t a b -> (a -> f b) -> s -> f t+lns (WrappedLensLike l) = l+{-# INLINE lns #-}++-- | /Since 0.4.2.0/+lns' :: WrappedLensLike' f s a -> (a -> f a) -> s -> f s+lns' (WrappedLensLike l) = l+{-# INLINE lns' #-}++-- }}} Lens -------------------------------------------------------------------+ -- {{{ Instances -------------------------------------------------------------- -- {{{ Instances -- Tuples ---------------------------------------------------- +-- {{{ Instances -- Tuples -- 2-tuple (pair) ----------------------------------+ -- | /Since 0.4.0.0/ type instance FieldType "fst" (a, b) = a @@ -475,6 +670,10 @@ modifyField _proxy f (a, b) = (a, f b) setField _proxy (a, _) b = (a, b) +-- }}} Instances -- Tuples -- 2-tuple (pair) ----------------------------------++-- {{{ Instances -- Tuples -- 3-tuple (triplet) -------------------------------+ -- | /Since 0.4.0.0/ type instance FieldType "fst" (a, b, c) = a @@ -527,6 +726,10 @@ modifyField _proxy f (a, b, c) = (a, b, f c) setField _proxy (a, b, _) c = (a, b, c) +-- }}} Instances -- Tuples -- 3-tuple (triplet) -------------------------------++-- {{{ Instances -- Tuples -- 4-tuple (quad) ----------------------------------+ -- | /Since 0.4.0.0/ type instance FieldType "fst" (a1, a2, a3, a4) = a1 @@ -581,6 +784,10 @@ where getField _proxy f a1 a2 a3 a4 = f (a1, a2, a3, a4) +-- }}} Instances -- Tuples -- 4-tuple (quad) ----------------------------------++-- {{{ Instances -- Tuples -- 5-tuple -----------------------------------------+ -- | /Since 0.4.0.0/ type instance FieldType "fst" (a1, a2, a3, a4, a5) = a1 @@ -642,6 +849,10 @@ where getField _proxy f a1 a2 a3 a4 a5 = f (a1, a2, a3, a4, a5) +-- }}} Instances -- Tuples -- 5-tuple -----------------------------------------++-- {{{ Instances -- Tuples -- 6-tuple -----------------------------------------+ -- | /Since 0.4.0.0/ type instance FieldType "fst" (a1, a2, a3, a4, a5, a6) = a1 @@ -707,6 +918,10 @@ where getField _proxy f a1 a2 a3 a4 a5 a6 = f (a1, a2, a3, a4, a5, a6) +-- }}} Instances -- Tuples -- 6-tuple -----------------------------------------++-- {{{ Instances -- Tuples -- 7-tuple -----------------------------------------+ -- | /Since 0.4.0.0/ type instance FieldType "fst" (a1, a2, a3, a4, a5, a6, a7) = a1 @@ -781,6 +996,10 @@ where getField _proxy f a1 a2 a3 a4 a5 a6 a7 = f (a1, a2, a3, a4, a5, a6, a7) +-- }}} Instances -- Tuples -- 7-tuple -----------------------------------------++-- {{{ Instances -- Tuples -- 8-tuple -----------------------------------------+ -- | /Since 0.4.0.0/ type instance FieldType "fst" (a1, a2, a3, a4, a5, a6, a7, a8) = a1 @@ -856,6 +1075,10 @@ getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 = f (a1, a2, a3, a4, a5, a6, a7, a8) +-- }}} Instances -- Tuples -- 8-tuple -----------------------------------------++-- {{{ Instances -- Tuples -- 9-tuple -----------------------------------------+ -- | /Since 0.4.0.0/ type instance FieldType "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9) = a1 @@ -931,6 +1154,10 @@ getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 = f (a1, a2, a3, a4, a5, a6, a7, a8, a9) +-- }}} Instances -- Tuples -- 9-tuple -----------------------------------------++-- {{{ Instances -- Tuples -- 10-tuple ----------------------------------------+ -- | /Since 0.4.0.0/ type instance FieldType "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = a1 @@ -1007,6 +1234,509 @@ getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 = f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) +-- }}} Instances -- Tuples -- 10-tuple ----------------------------------------++-- {{{ Instances -- Tuples -- 11-tuple ----------------------------------------++-- | /Since 0.4.2.0/+type instance FieldType "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) = a1++-- | /Since 0.4.2.0/+type instance UpdateType "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a1' =+ (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)++-- | /Since 0.4.2.0/+type instance FieldType "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) = a2++-- | /Since 0.4.2.0/+type instance UpdateType "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a2' =+ (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11)++-- | /Since 0.4.2.0/+type instance FieldType "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) = a3++-- | /Since 0.4.2.0/+type instance UpdateType "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a3' =+ (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11)++-- | /Since 0.4.2.0/+type instance FieldType "curry"+ ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) -> r) =+ a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> r++-- | /Since 0.4.2.0/+instance HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a1 where+ getField _proxy (a1, _, _, _, _, _, _, _, _, _, _) = a1++-- | /Since 0.4.2.0/+instance HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a2 where+ getField _proxy (_, a2, _, _, _, _, _, _, _, _, _) = a2++-- | /Since 0.4.2.0/+instance HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a3 where+ getField _proxy (_, _, a3, _, _, _, _, _, _, _, _) = a3++-- | /Since 0.4.2.0/+instance+ ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)+ (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a1 a1'+ where+ modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) =+ (f a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)+ setField _proxy (_, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a1 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)++-- | /Since 0.4.2.0/+instance+ ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)+ (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11) a2 a2'+ where+ modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) =+ (a1, f a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)+ setField _proxy (a1, _, a3, a4, a5, a6, a7, a8, a9, a10, a11) a2 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)++-- | /Since 0.4.2.0/+instance+ ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)+ (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11) a3 a3'+ where+ modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) =+ (a1, a2, f a3, a4, a5, a6, a7, a8, a9, a10, a11)+ setField _proxy (a1, a2, _, a4, a5, a6, a7, a8, a9, a10, a11) a3 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)++-- | /Since 0.4.2.0/+instance+ HasField "curry" ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) -> r)+ (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> r)+ where+ getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 =+ f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)++-- }}} Instances -- Tuples -- 11-tuple ----------------------------------------++-- {{{ Instances -- Tuples -- 12-tuple ----------------------------------------++-- | /Since 0.4.2.0/+type instance FieldType "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) = a1++-- | /Since 0.4.2.0/+type instance UpdateType "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a1' =+ (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)++-- | /Since 0.4.2.0/+type instance FieldType "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) = a2++-- | /Since 0.4.2.0/+type instance UpdateType "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a2' =+ (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)++-- | /Since 0.4.2.0/+type instance FieldType "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) = a3++-- | /Since 0.4.2.0/+type instance UpdateType "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a3' =+ (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12)++-- | /Since 0.4.2.0/+type instance FieldType "curry"+ ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) -> r) =+ a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> a12+ -> r++-- | /Since 0.4.2.0/+instance HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a1+ where+ getField _proxy (a1, _, _, _, _, _, _, _, _, _, _, _) = a1++-- | /Since 0.4.2.0/+instance HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a2+ where+ getField _proxy (_, a2, _, _, _, _, _, _, _, _, _, _) = a2++-- | /Since 0.4.2.0/+instance HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a3+ where+ getField _proxy (_, _, a3, _, _, _, _, _, _, _, _, _) = a3++-- | /Since 0.4.2.0/+instance+ ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)+ (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a1 a1'+ where+ modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) =+ (f a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)+ setField _proxy (_, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a1 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)++-- | /Since 0.4.2.0/+instance+ ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)+ (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a2 a2'+ where+ modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) =+ (a1, f a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)+ setField _proxy (a1, _, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a2 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)++-- | /Since 0.4.2.0/+instance+ ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)+ (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12) a3 a3'+ where+ modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) =+ (a1, a2, f a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)+ setField _proxy (a1, a2, _, a4, a5, a6, a7, a8, a9, a10, a11, a12) a3 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)++-- | /Since 0.4.2.0/+instance+ HasField "curry" ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) -> r)+ ( a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11+ -> a12 -> r+ )+ where+ getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 =+ f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)++-- }}} Instances -- Tuples -- 12-tuple ----------------------------------------++-- {{{ Instances -- Tuples -- 13-tuple ----------------------------------------++-- | /Since 0.4.2.0/+type instance FieldType "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) = a1++-- | /Since 0.4.2.0/+type instance UpdateType "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a1' =+ (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)++-- | /Since 0.4.2.0/+type instance FieldType "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) = a2++-- | /Since 0.4.2.0/+type instance UpdateType "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a2' =+ (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)++-- | /Since 0.4.2.0/+type instance FieldType "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) = a3++-- | /Since 0.4.2.0/+type instance UpdateType "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a3' =+ (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)++-- | /Since 0.4.2.0/+type instance FieldType "curry"+ ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) -> r) =+ a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> a12+ -> a13 -> r++-- | /Since 0.4.2.0/+instance+ HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a1+ where+ getField _proxy (a1, _, _, _, _, _, _, _, _, _, _, _, _) = a1++-- | /Since 0.4.2.0/+instance+ HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a2+ where+ getField _proxy (_, a2, _, _, _, _, _, _, _, _, _, _, _) = a2++-- | /Since 0.4.2.0/+instance+ HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a3+ where+ getField _proxy (_, _, a3, _, _, _, _, _, _, _, _, _, _) = a3++-- | /Since 0.4.2.0/+instance+ ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)+ (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a1 a1'+ where+ modifyField _proxy f+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) =+ (f a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)+ setField _proxy+ (_, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a1 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)++-- | /Since 0.4.2.0/+instance+ ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)+ (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a2 a2'+ where+ modifyField _proxy f+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) =+ (a1, f a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)+ setField _proxy+ (a1, _, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a2 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)++-- | /Since 0.4.2.0/+instance+ ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)+ (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a3 a3'+ where+ modifyField _proxy f+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) =+ (a1, a2, f a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)+ setField _proxy+ (a1, a2, _, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a3 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)++-- | /Since 0.4.2.0/+instance+ HasField "curry"+ ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) -> r)+ ( a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11+ -> a12 -> a13 -> r+ )+ where+ getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 =+ f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)++-- }}} Instances -- Tuples -- 13-tuple ----------------------------------------++-- {{{ Instances -- Tuples -- 14-tuple ----------------------------------------++-- | /Since 0.4.2.0/+type instance FieldType "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) = a1++-- | /Since 0.4.2.0/+type instance UpdateType "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a1' =+ (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)++-- | /Since 0.4.2.0/+type instance FieldType "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) = a2++-- | /Since 0.4.2.0/+type instance UpdateType "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a2' =+ (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)++-- | /Since 0.4.2.0/+type instance FieldType "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) = a3++-- | /Since 0.4.2.0/+type instance UpdateType "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a3' =+ (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)++-- | /Since 0.4.2.0/+type instance FieldType "curry"+ ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) -> r) =+ a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> a12+ -> a13 -> a14 -> r++-- | /Since 0.4.2.0/+instance+ HasField "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a1+ where+ getField _proxy (a1, _, _, _, _, _, _, _, _, _, _, _, _, _) = a1++-- | /Since 0.4.2.0/+instance+ HasField "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a2+ where+ getField _proxy (_, a2, _, _, _, _, _, _, _, _, _, _, _, _) = a2++-- | /Since 0.4.2.0/+instance+ HasField "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a3+ where+ getField _proxy (_, _, a3, _, _, _, _, _, _, _, _, _, _, _) = a3++-- | /Since 0.4.2.0/+instance+ ModifyField "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)+ (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a1 a1'+ where+ modifyField _proxy f+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) =+ (f a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)+ setField _proxy+ (_, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a1 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)++-- | /Since 0.4.2.0/+instance+ ModifyField "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)+ (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a2 a2'+ where+ modifyField _proxy f+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) =+ (a1, f a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)+ setField _proxy+ (a1, _, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a2 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)++-- | /Since 0.4.2.0/+instance+ ModifyField "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)+ (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a3 a3'+ where+ modifyField _proxy f+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) =+ (a1, a2, f a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)+ setField _proxy+ (a1, a2, _, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a3 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)++-- | /Since 0.4.2.0/+instance+ HasField "curry"+ ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) -> r)+ ( a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11+ -> a12 -> a13 -> a14 -> r+ )+ where+ getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 =+ f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)++-- }}} Instances -- Tuples -- 14-tuple ----------------------------------------++-- {{{ Instances -- Tuples -- 15-tuple ----------------------------------------++-- | /Since 0.4.2.0/+type instance FieldType "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) = a1++-- | /Since 0.4.2.0/+type instance UpdateType "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a1' =+ (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)++-- | /Since 0.4.2.0/+type instance FieldType "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) = a2++-- | /Since 0.4.2.0/+type instance UpdateType "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a2' =+ (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)++-- | /Since 0.4.2.0/+type instance FieldType "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) = a3++-- | /Since 0.4.2.0/+type instance UpdateType "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a3' =+ (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)++-- | /Since 0.4.2.0/+type instance FieldType "curry"+ ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) -> r) =+ a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> a12+ -> a13 -> a14 -> a15 -> r++-- | /Since 0.4.2.0/+instance+ HasField "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a1+ where+ getField _proxy (a1, _, _, _, _, _, _, _, _, _, _, _, _, _, _) = a1++-- | /Since 0.4.2.0/+instance+ HasField "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a2+ where+ getField _proxy (_, a2, _, _, _, _, _, _, _, _, _, _, _, _, _) = a2++-- | /Since 0.4.2.0/+instance+ HasField "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a3+ where+ getField _proxy (_, _, a3, _, _, _, _, _, _, _, _, _, _, _, _) = a3++-- | /Since 0.4.2.0/+instance+ ModifyField "fst"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)+ (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)+ a1 a1'+ where+ modifyField _proxy f+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) =+ (f a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)+ setField _proxy+ (_, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a1 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)++-- | /Since 0.4.2.0/+instance+ ModifyField "snd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)+ (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)+ a2 a2'+ where+ modifyField _proxy f+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) =+ (a1, f a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)+ setField _proxy+ (a1, _, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a2 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)++-- | /Since 0.4.2.0/+instance+ ModifyField "thd"+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)+ (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)+ a3 a3'+ where+ modifyField _proxy f+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) =+ (a1, a2, f a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)+ setField _proxy+ (a1, a2, _, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a3 =+ (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)++-- | /Since 0.4.2.0/+instance+ HasField "curry"+ ( (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)+ -> r+ )+ ( a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11+ -> a12 -> a13 -> a14 -> a15 -> r+ )+ where+ getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 =+ f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)++-- }}} Instances -- Tuples -- 15-tuple ----------------------------------------+ -- }}} Instances -- Tuples ---------------------------------------------------- -- {{{ Instances -- Lists -----------------------------------------------------@@ -1062,6 +1792,7 @@ -- | /Since 0.4.0.0/ type instance FieldType "tail" [a] = Maybe [a]+ -- | /Since 0.4.0.0/ type instance UpdateType "tail" [a] (Maybe [a]) = [a] @@ -1109,6 +1840,74 @@ Just as -> a : as -- }}} Instances -- Lists -----------------------------------------------------++#ifdef HAVE_NON_EMPTY_LIST+-- {{{ Instances -- Non-empty Lists -------------------------------------------++-- | /Since 0.4.2.0/+type instance FieldType "head" (NonEmpty a) = a++-- | /Since 0.4.2.0/+type instance UpdateType "head" (NonEmpty a) a = NonEmpty a++-- |+-- >>> #head 1 :| []+-- 1+--+-- >>> #head (1 :| [2, 3])+-- 1+--+-- /Since 0.4.2.0/+instance HasField "head" (NonEmpty a) a where+ getField _proxy (a :| _) = a++-- |+-- >>> set' #head [1, 2, 3] 4+-- [4, 2, 3]+--+-- /Since 0.4.2.0/+instance ModifyField "head" (NonEmpty a) (NonEmpty a) a a where+ modifyField _proxy f (a :| as) = f a :| as+ setField _proxy (_ :| as) a = a :| as++-- | /Since 0.4.2.0/+type instance FieldType "tail" (NonEmpty a) = [a]++-- | /Since 0.4.2.0/+type instance UpdateType "tail" (NonEmpty a) [a] = NonEmpty a++-- |+-- >>> #tail (1 :| [])+-- []+--+-- >>> #tail (1 :| [2, 3])+-- [2, 3]+--+-- /Since 0.4.2.0/+instance HasField "tail" (NonEmpty a) [a] where+ getField _proxy (_ :| as) = as++-- |+-- >>> set' #tail (1 :| []) []+-- (1 :| [])+--+-- >>> set' #tail (1 :| []) [2, 3]+-- 1 :| [2, 3]+--+-- >>> set' #tail (1 :| [2, 3]) []+-- 1 :| []+--+-- >>> set' #tail (1 :| [2, 3]) [4, 5, 6]+-- 1 :| [4, 5, 6]+--+-- /Since 0.4.2.0/+instance ModifyField "tail" (NonEmpty a) (NonEmpty a) [a] [a] where+ modifyField _proxy f (a :| as) = a :| f as+ setField _proxy (a :| _) as = a :| as++-- }}} Instances -- Non-empty Lists -------------------------------------------+#endif+ -- HAVE_NON_EMPTY_LIST -- }}} Instances --------------------------------------------------------------
src/Data/OverloadedRecords/TH/Internal.hs view
@@ -85,6 +85,7 @@ import Prelude (Num((-)), fromIntegral) import Control.Applicative (Applicative((<*>)))+import Control.Arrow (Arrow((***))) import Control.Monad (Monad((>>=) _FAIL_IN_MONAD, return), replicateM) #if 0 #if HAVE_MONAD_FAIL && MIN_VERSION_template_haskell(2,11,0)@@ -93,8 +94,9 @@ #endif import Data.Bool (Bool(False), otherwise) import qualified Data.Char as Char (toLower)+import Data.Eq (Eq((==))) import Data.Foldable (concat, foldl)-import Data.Function ((.), ($))+import Data.Function ((.), ($), flip) import Data.Functor (Functor(fmap), (<$>)) import qualified Data.List as List ( drop@@ -103,11 +105,14 @@ , map , replicate , zip+ , lookup+ , unzip )-import Data.Maybe (Maybe(Just, Nothing), fromMaybe)+import Data.Maybe (Maybe(Just, Nothing), fromMaybe, catMaybes) import Data.Monoid ((<>)) import Data.String (String)-import Data.Traversable (forM, mapM)+import Data.Traversable (mapM, sequence)+import Data.Tuple (fst) import Data.Typeable (Typeable) import Data.Word (Word) import GHC.Generics (Generic)@@ -165,7 +170,9 @@ import Data.OverloadedRecords ( FieldType , HasField(getField)- , ModifyField(setField)+ , ModifyField(modifyField, setField)+ , ModifyRec(getRecField, modifyRecField, setRecField)+ , Rec , UpdateType ) @@ -318,6 +325,8 @@ } -- | Derive magic OverloadedRecordFields instances for specified type.+-- Fails if different record fields within the same type would map to the+-- same overloaded label. overloadedRecord :: DeriveOverloadedRecordsParams -- ^ Parameters for customization of deriving process. Use 'def' to get@@ -334,14 +343,21 @@ #else NewtypeD [] typeName typeVars constructor _deriving -> #endif- deriveForConstructor params typeName typeVars constructor+ fst $ deriveForConstructor params [] typeName typeVars constructor #if MIN_VERSION_template_haskell(2,11,0) DataD [] typeName typeVars _kindSignature constructors _deriving -> #else DataD [] typeName typeVars constructors _deriving -> #endif- fmap concat . forM constructors- $ deriveForConstructor params typeName typeVars+ fst $ foldl go (return [], []) constructors+ where+ go :: (DecsQ, [(String, String)])+ -> Con+ -> (DecsQ, [(String, String)])+ go (decs, seen) con =+ let (decs', seen') =+ deriveForConstructor params seen typeName typeVars con+ in ((<>) <$> decs <*> decs', seen <> seen') x -> canNotDeriveError name x x -> canNotDeriveError name x@@ -411,11 +427,14 @@ :: DeriveOverloadedRecordsParams -- ^ Parameters for customization of deriving process. Use 'def' to get -- default behaviour.+ -> [(String, String)]+ -- ^ Pairs of instances already generated along with the field names+ -- they were made from. -> Name -> [TyVarBndr] -> Con- -> DecsQ-deriveForConstructor params name typeVars = \case+ -> (DecsQ, [(String, String)])+deriveForConstructor params seen name typeVars = \case NormalC constructorName args -> deriveFor constructorName args $ \(strict, argType) f -> f Nothing strict argType@@ -429,22 +448,25 @@ f Nothing strict argType #if MIN_VERSION_template_haskell(2,11,0)- GadtC _ _ _ -> fail "GADTs aren't yet supported."- RecGadtC _ _ _ -> fail "GADTs aren't yet supported."+ GadtC _ _ _ -> (fail "GADTs aren't yet supported.", [])+ RecGadtC _ _ _ -> (fail "GADTs aren't yet supported.", []) #endif -- Existentials aren't supported.- ForallC _typeVariables _context _constructor -> return []+ ForallC _typeVariables _context _constructor -> (return [], []) where deriveFor :: Name -> [a]- -> (a -> (Maybe Name -> Strict -> Type -> DecsQ) -> DecsQ)- -> DecsQ+ -> ( a+ -> (Maybe Name -> Strict -> Type -> (DecsQ, Maybe (String, String)))+ -> (DecsQ, Maybe (String, String))+ )+ -> (DecsQ, [(String, String)]) deriveFor constrName args f =- fmap concat . forM (withIndexes args) $ \(idx, arg) ->+ concatBoth . flip fmap (withIndexes args) $ \(idx, arg) -> f arg $ \accessor strict fieldType' ->- deriveForField params DeriveFieldParams+ deriveForField params seen DeriveFieldParams { typeName = name , typeVariables = List.map getTypeName typeVars , constructorName = constrName@@ -460,6 +482,9 @@ PlainTV n -> n KindedTV n _kind -> n + concatBoth :: [(Q [a], Maybe b)] -> (Q [a], [b])+ concatBoth = (fmap concat . sequence *** catMaybes) . List.unzip+ withIndexes = List.zip [(0 :: Word) ..] -- | Parameters for 'deriveForField' function.@@ -490,18 +515,27 @@ :: DeriveOverloadedRecordsParams -- ^ Parameters for customization of deriving process. Use 'def' to get -- default behaviour.+ -> [(String, String)]+ -- ^ Pairs of instances already generated along with the field names+ -- they were made from. -> DeriveFieldParams -- ^ All the necessary information for derivation procedure.- -> DecsQ-deriveForField params DeriveFieldParams{..} =+ -> (DecsQ, Maybe (String, String))+ -- If instances were generated, then the second part is a pair+ -- (instanceLabel, fieldLabel), i.e. witness of defined of created+ -- instance. It's later used to ideintify duplicities.+deriveForField params seen DeriveFieldParams{..} = case possiblyLabel of- Nothing -> return []+ Nothing -> (return [], Nothing)+ Just (GetterOnlyField label customGetterExpr) ->- deriveGetter' (strTyLitT label)+ ifNotSeenAlreadyThenDo label . deriveGetter' (strTyLitT label) $ fromMaybe derivedGetterExpr customGetterExpr- Just (GetterAndSetterField label customGetterAndSetterExpr) -> (<>)- <$> deriveGetter' labelType getterExpr- <*> deriveSetter' labelType setterExpr++ Just (GetterAndSetterField label customGetterAndSetterExpr) ->+ ifNotSeenAlreadyThenDo label $ (<>)+ <$> deriveGetter' labelType getterExpr+ <*> deriveSetter' labelType setterExpr where labelType = strTyLitT label @@ -509,8 +543,27 @@ fromMaybe (derivedGetterExpr, derivedSetterExpr) customGetterAndSetterExpr where+ accessorBase = fmap nameBase accessorName++ ifNotSeenAlreadyThenDo+ :: String+ -> DecsQ+ -> (DecsQ, Maybe (String, String))+ ifNotSeenAlreadyThenDo label action =+ case List.lookup label seen of+ x@(Just from)+ -- Same instance, for the same accessor was already defined,+ -- skipping.+ | x == accessorBase -> (return [], Nothing)+ -- Two different accessors with the same name, this is not resovable.+ | otherwise -> (nameConflictError from, Nothing)+ Nothing -> (action, (,) label <$> accessorBase)++ nameConflictError n =+ fail $ "Two different fields map to the same label \"" <> n <> "\""+ possiblyLabel = _fieldDerivation params (nameBase typeName)- (nameBase constructorName) currentIndex (fmap nameBase accessorName)+ (nameBase constructorName) currentIndex accessorBase deriveGetter' labelType = deriveGetter labelType recordType (return fieldType)@@ -623,6 +676,12 @@ instance HasField $(labelType) $(recordType) $(fieldType) where getField _proxy = $(getter)++ instance+ ( ModifyRec $(labelType) $(fieldType) cs+ ) => HasField $(labelType) (Rec cs $(recordType)) $(fieldType)+ where+ getField = getRecField |] -- | Derive instances for overloaded record field setter. Same as@@ -669,6 +728,15 @@ $(fieldType) $(newFieldType) where setField _proxy = $(setter)++ -- TODO: Type changing assignment and modification.+ instance+ ( ModifyRec $(labelType) $(fieldType) cs+ ) => ModifyField $(labelType) (Rec cs $(recordType))+ (Rec cs $(recordType)) $(fieldType) $(fieldType)+ where+ setField = setRecField+ modifyField = modifyRecField |] -- | Construct list of wildcard patterns ('WildP').
test/TestCase/Data/OverloadedRecords.hs view
@@ -79,8 +79,15 @@ instance ModifyField "snd" (Pair a b) (Pair a b') b b' where setField _proxy (Pair a _) b' = Pair a b' -labels ["fst", "snd", "head", "tail"]+-- {{{ Test, that we can have same accessor for multiple constructors.+data AB = A {_size :: Int} | B {_size :: Int}+ deriving (Eq, Show) +overloadedRecord def ''AB+-- }}} Test, that we can have same accessor for multiple constructors.++labels ["fst", "snd", "head", "tail", "size"]+ tests :: [Test] tests = [ testGroup "defaultMakeFieldName" $ map test_defaultMakeField@@ -175,6 +182,16 @@ , testCase "[1, 2, 3] & simple . #tail .~ Just [4, 5, 6] = [1, 4, 5, 6]" $ ([1, 2, 3] & simple . tail .~ Just [4, 5, 6]) @?= [1, 4, 5, 6 :: Int]+ ]++ -- Mostly just a sanity check that instances for AB work correctly.+ , testGroup "#tail for data AB = A {_size :: Int} | B {_size :: Int}"+ [ testCase "#size (A 10) = 10" $ size (A 10) @?= 10+ , testCase "A 10 & simple . #size .~ 42 = A 42"+ $ (A 10 & simple . size .~ 42) @?= A 42+ , testCase "#size (B 10) = 10" $ size (B 10) @?= 10+ , testCase "B 10 & simple . #size .~ 42 = A 42"+ $ (B 10 & simple . size .~ 42) @?= B 42 ] ] where