extensible 0.8.3 → 0.9
raw patch · 9 files changed
+55/−56 lines, 9 filesdep ~aesondep ~hashablePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: aeson, hashable
API changes (from Hackage documentation)
- Data.Extensible.Dictionary: instance forall k (h :: k -> Type) (xs :: [k]). Data.Extensible.Dictionary.WrapForall Data.Hashable.Class.Hashable h xs => Data.Hashable.Class.Hashable (xs Data.Extensible.Struct.:& h)
- Data.Extensible.Dictionary: instance forall k (h :: k -> Type) (xs :: [k]). Data.Extensible.Dictionary.WrapForall Data.Hashable.Class.Hashable h xs => Data.Hashable.Class.Hashable (xs Data.Extensible.Sum.:/ h)
- Data.Extensible.Field: data Inextensible (xs :: [k]) (h :: k -> Type)
- Data.Extensible.Field: data LabelPhantom s a b
- Data.Extensible.Field: instance (GHC.Base.Functor f, Data.Profunctor.Unsafe.Profunctor p) => Data.Extensible.Class.Extensible f p Data.Extensible.Field.Inextensible
- Data.Extensible.Field: instance forall k (s :: k). Data.Profunctor.Unsafe.Profunctor (Data.Extensible.Field.LabelPhantom s)
- Data.Extensible.Field: type FieldName k = Optic' (LabelPhantom k) Proxy (Inextensible '[k :> ()] (Field Proxy)) ()
- Data.Extensible.Label: instance (k GHC.Types.~ l) => GHC.OverloadedLabels.IsLabel k (Data.Proxy.Proxy l)
- Data.Extensible.Label: instance forall k1 v1 (xs :: [Type.Membership.Internal.Assoc k1 v1]) (k2 :: k1) (v2 :: v1) (h :: v1 -> Type) a. (Type.Membership.Internal.Lookup xs k2 v2, Data.Extensible.Wrapper.Wrapper h, Data.Extensible.Wrapper.Repr h v2 GHC.Types.~ a) => GHC.Records.HasField k2 (Data.Extensible.Field.RecordOf h xs) a
- Data.Extensible.Label: instance forall v1 (f :: Type -> Type) (p :: Type -> Type -> Type) (e :: [Type.Membership.Internal.Assoc GHC.Types.Symbol v1] -> (Type.Membership.Internal.Assoc GHC.Types.Symbol v1 -> Type) -> Type) (xs :: [Type.Membership.Internal.Assoc GHC.Types.Symbol v1]) (k :: GHC.Types.Symbol) (v2 :: v1) (h :: v1 -> Type) rep s t rep'. (Data.Extensible.Class.Extensible f p e, Type.Membership.Internal.Lookup xs k v2, Data.Extensible.Field.Labelling k p, Data.Extensible.Wrapper.Wrapper h, Data.Extensible.Class.ExtensibleConstr e xs (Data.Extensible.Field.Field h) (k 'Type.Membership.Internal.:> v2), rep GHC.Types.~ Data.Extensible.Wrapper.Repr h v2, s GHC.Types.~ e xs (Data.Extensible.Field.Field h), s GHC.Types.~ t, rep GHC.Types.~ rep') => GHC.OverloadedLabels.IsLabel k (p rep (f rep') -> p s (f t))
- Data.Extensible.Label: xlb :: Proxy k -> FieldOptic k
+ Data.Extensible.Dictionary: instance forall k (h :: k -> Type) (xs :: [k]). (Data.Extensible.Dictionary.WrapForall GHC.Classes.Eq h xs, Data.Extensible.Dictionary.WrapForall Data.Hashable.Class.Hashable h xs) => Data.Hashable.Class.Hashable (xs Data.Extensible.Struct.:& h)
+ Data.Extensible.Dictionary: instance forall k (h :: k -> Type) (xs :: [k]). (Data.Extensible.Dictionary.WrapForall GHC.Classes.Eq h xs, Data.Extensible.Dictionary.WrapForall Data.Hashable.Class.Hashable h xs) => Data.Hashable.Class.Hashable (xs Data.Extensible.Sum.:/ h)
+ Data.Extensible.Dictionary: instance forall k1 v1 (xs :: [Type.Membership.Internal.Assoc k1 v1]) (k2 :: k1) (v2 :: v1) (h :: v1 -> Type) a. (Type.Membership.Internal.Lookup xs k2 v2, Data.Extensible.Wrapper.Wrapper h, Data.Extensible.Wrapper.Repr h v2 GHC.Types.~ a) => GHC.Records.HasField k2 (Data.Extensible.Field.RecordOf h xs) a
+ Data.Extensible.Field: instance (k GHC.Types.~ l) => GHC.OverloadedLabels.IsLabel k (Data.Proxy.Proxy l)
+ Data.Extensible.Field: xlb :: Proxy k -> FieldOptic k
+ Data.Extensible.Label: instance forall v1 (f :: Type -> Type) (p :: Type -> Type -> Type) (e :: [Type.Membership.Internal.Assoc GHC.Types.Symbol v1] -> (Type.Membership.Internal.Assoc GHC.Types.Symbol v1 -> Type) -> Type) (xs :: [Type.Membership.Internal.Assoc GHC.Types.Symbol v1]) (k :: GHC.Types.Symbol) (v2 :: v1) (h :: v1 -> Type) rep s t rep'. (Data.Extensible.Class.Extensible f p e, Type.Membership.Internal.Lookup xs k v2, Data.Extensible.Wrapper.Wrapper h, Data.Extensible.Class.ExtensibleConstr e xs (Data.Extensible.Field.Field h) (k 'Type.Membership.Internal.:> v2), rep GHC.Types.~ Data.Extensible.Wrapper.Repr h v2, s GHC.Types.~ e xs (Data.Extensible.Field.Field h), s GHC.Types.~ t, rep GHC.Types.~ rep') => GHC.OverloadedLabels.IsLabel k (p rep (f rep') -> p s (f t))
- Data.Extensible.Field: (<@=>) :: (Functor f, Wrapper h) => FieldName k -> f (Repr h v) -> Compose f (Field h) (k :> v)
+ Data.Extensible.Field: (<@=>) :: (Functor f, Wrapper h) => Proxy k -> f (Repr h v) -> Compose f (Field h) (k :> v)
- Data.Extensible.Field: (@:>) :: FieldName k -> h v -> Field h (k :> v)
+ Data.Extensible.Field: (@:>) :: Proxy k -> h v -> Field h (k :> v)
- Data.Extensible.Field: (@=) :: Wrapper h => FieldName k -> Repr h v -> Field h (k :> v)
+ Data.Extensible.Field: (@=) :: Wrapper h => Proxy k -> Repr h v -> Field h (k :> v)
- Data.Extensible.Field: (@==) :: FieldName (k :: Symbol) -> v -> Field Identity (k :> v)
+ Data.Extensible.Field: (@==) :: Proxy (k :: Symbol) -> v -> Field Identity (k :> v)
- Data.Extensible.Field: type FieldOptic k = forall kind. forall f p t xs (h :: kind -> Type) (v :: kind). (Extensible f p t, ExtensibleConstr t xs (Field h) (k :> v), Lookup xs k v, Labelling k p, Wrapper h) => Optic' p f (t xs (Field h)) (Repr h v)
+ Data.Extensible.Field: type FieldOptic k = forall kind. forall f p t xs (h :: kind -> Type) (v :: kind). (Extensible f p t, ExtensibleConstr t xs (Field h) (k :> v), Lookup xs k v, Wrapper h) => Optic' p f (t xs (Field h)) (Repr h v)
- Data.Extensible.Field: type family Labelling s p :: Constraint
+ Data.Extensible.Field: type family TargetOf (kv :: Assoc k v) :: v
- Data.Extensible.Tangle: lasso :: forall k v m h xs. (Monad m, Lookup xs k v, Wrapper h) => FieldName k -> TangleT xs h m (Repr h (k :> v))
+ Data.Extensible.Tangle: lasso :: forall k v m h xs. (Monad m, Lookup xs k v, Wrapper h) => Proxy k -> TangleT xs h m (Repr h (k :> v))
Files
- .gitignore +1/−0
- CHANGELOG.md +8/−0
- extensible.cabal +14/−5
- src/Data/Extensible.hs +3/−2
- src/Data/Extensible/Dictionary.hs +11/−2
- src/Data/Extensible/Field.hs +11/−29
- src/Data/Extensible/Label.hs +1/−14
- src/Data/Extensible/TH.hs +4/−2
- src/Data/Extensible/Tangle.hs +2/−2
.gitignore view
@@ -11,6 +11,7 @@ cabal.config .stack-work .bash_history+dist-newstyle # ========================= # Operating System Files
CHANGELOG.md view
@@ -1,3 +1,11 @@+0.9+------------------------------------------------++* Removed `FieldName`, the relic of the old ages+ * `(@=)`, `@==`, `@!?` and `lasso` now take `Proxy` instead of `FieldName`. Those who are using `mkField` need to replace the operands with proxies (OverloadedLabels is recommended).+* Supported aeson 1.x+* Introduced `IsLabel` flag which toggles the presence of optics `OverloadedLabels`. By disabling it, this package can now coexist with other users of the `IsLabel` class, such as `generic-lens` and `relational-query`.+ 0.8.3 ------------------------------------------------
extensible.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: extensible-version: 0.8.3+version: 0.9 synopsis: Extensible, efficient, optics-friendly data types and effects homepage: https://github.com/fumieval/extensible bug-reports: http://github.com/fumieval/extensible/issues@@ -12,11 +12,11 @@ license-file: LICENSE author: Fumiaki Kinoshita maintainer: Fumiaki Kinoshita <fumiexcel@gmail.com>-copyright: Copyright (c) 2017-2021 Fumiaki Kinoshita+copyright: Copyright (c) 2017-2022 Fumiaki Kinoshita category: Data, Records build-type: Simple stability: experimental-Tested-With: GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.4, GHC == 9.0.1+Tested-With: GHC == 8.10.7, GHC == 9.0.1, GHC == 9.2.1 extra-source-files: examples/*.hs@@ -31,11 +31,18 @@ flag barbies default: False description: "define instances for barbies"+ manual: True flag cassava default: True description: "define instances for cassava"+ manual: True +flag IsLabel+ default: True+ description: "export the instance of IsLabel making optics (which could conflict with other packages such as generic-lens)"+ manual: True+ library exposed-modules: Data.Extensible@@ -73,13 +80,13 @@ , CPP , NoStarIsType build-depends: base >= 4.8 && <5- , aeson ^>= 2.0+ , aeson >= 1.5 && <2.1 , bytestring , comonad , constraints , deepseq , ghc-prim- , hashable+ , hashable >= 1.2 && <1.5 , incremental >= 0.3.1 , membership , prettyprinter ^>= 1.7@@ -100,6 +107,8 @@ if flag(cassava) build-depends: cassava cpp-options: -DCASSAVA+ if flag(IsLabel)+ cpp-options: -DISLABEL hs-source-dirs: src ghc-options: -Wall -Wcompat default-language: Haskell2010
src/Data/Extensible.hs view
@@ -32,7 +32,6 @@ , module Data.Extensible.Dictionary , module Data.Extensible.Field , module Data.Extensible.Inclusion- , module Data.Extensible.Label , module Data.Extensible.Match , module Data.Extensible.Nullable , module Data.Extensible.Product@@ -51,7 +50,9 @@ import Data.Extensible.Dictionary import Data.Extensible.Field import Data.Extensible.Inclusion-import Data.Extensible.Label+#ifdef ISLABEL+import Data.Extensible.Label ()+#endif import Data.Extensible.Match import Data.Extensible.Nullable import Data.Extensible.Product
src/Data/Extensible/Dictionary.hs view
@@ -35,8 +35,13 @@ import Data.Extensible.Nullable import Data.Constraint import Data.Extensible.Struct+import Data.Extensible.Wrapper import Data.Hashable+#if MIN_VERSION_aeson(2,0,0) import qualified Data.Aeson.KeyMap as KM+#else+import qualified Data.HashMap.Strict as KM+#endif import Data.Functor.Compose import qualified Data.HashMap.Strict as HM import Data.Incremental@@ -52,6 +57,7 @@ import qualified Language.Haskell.TH.Syntax as TH #endif import Language.Haskell.TH hiding (Type)+import GHC.Records import GHC.TypeLits import Test.QuickCheck.Arbitrary import Test.QuickCheck.Gen@@ -105,7 +111,7 @@ mappend = (<>) {-# INLINE mappend #-} -instance WrapForall Hashable h xs => Hashable (xs :& h) where+instance (WrapForall Eq h xs, WrapForall Hashable h xs) => Hashable (xs :& h) where hashWithSalt = hfoldlWithIndexFor (Proxy :: Proxy (Instance1 Hashable h)) (const hashWithSalt) {-# INLINE hashWithSalt #-}@@ -261,7 +267,7 @@ rnf (EmbedAt i h) = views (pieceAt i) (\(Compose Dict) -> rnf h) (library :: xs :& Compose Dict (Instance1 NFData h)) {-# INLINE rnf #-} -instance WrapForall Hashable h xs => Hashable (xs :/ h) where+instance (WrapForall Eq h xs, WrapForall Hashable h xs) => Hashable (xs :/ h) where hashWithSalt s (EmbedAt i h) = views (pieceAt i) (\(Compose Dict) -> s `hashWithSalt` i `hashWithSalt` h) (library :: xs :& Compose Dict (Instance1 Hashable h))@@ -345,3 +351,6 @@ check t | getAny $ hfoldMap (Any . isJust . unwrapDelta) t = Just t | otherwise = Nothing++instance (Lookup xs k v, Wrapper h, Repr h v ~ a) => HasField k (RecordOf h xs) a where+ getField = unwrap . hlookup (association :: Membership xs (k >: v))
src/Data/Extensible/Field.hs view
@@ -22,7 +22,7 @@ , (@:>) , (@==) , FieldOptic- , FieldName+ , xlb , liftField , liftField2 -- * Records and variants@@ -43,10 +43,6 @@ , KeyIs , TargetIs , KeyTargetAre- -- * Internal- , LabelPhantom- , Labelling- , Inextensible ) where import Control.DeepSeq (NFData) import qualified Data.Aeson as J@@ -72,6 +68,7 @@ import qualified Data.Vector.Generic.Mutable as M import qualified Data.Vector.Unboxed as U import Foreign.Storable (Storable)+import GHC.OverloadedLabels import GHC.Generics (Generic) import GHC.TypeLits hiding (Nat) import Language.Haskell.TH.Lift@@ -241,30 +238,15 @@ (Extensible f p t , ExtensibleConstr t xs (Field h) (k ':> v) , Lookup xs k v- , Labelling k p , Wrapper h) => Optic' p f (t xs (Field h)) (Repr h v) --- | The trivial inextensible data type-data Inextensible (xs :: [k]) (h :: k -> Type)--instance (Functor f, Profunctor p) => Extensible f p Inextensible where- pieceAt _ _ = error "Impossible"---- | When you see this type as an argument, it expects a 'FieldLens'.--- This type is used to resolve the name of the field internally.-type FieldName k = Optic' (LabelPhantom k) Proxy (Inextensible '[k ':> ()] (Field Proxy)) ()---- | Signifies a field name internally-type family Labelling s p :: Constraint where- Labelling s (LabelPhantom t) = s ~ t- Labelling s p = ()---- | A ghostly type which spells the field name-data LabelPhantom s a b+instance k ~ l => IsLabel k (Proxy l) where+ fromLabel = Proxy -instance Profunctor (LabelPhantom s) where- dimap _ _ _ = error "Impossible"+-- | Specialised version of 'itemAssoc'. Stands for "eXtensible LaBel"+xlb :: Proxy k -> FieldOptic k+xlb t = itemAssoc t -- | Annotate a value by the field name. --@@ -274,7 +256,7 @@ -- <: #str \@= "foo" -- <: nil -- @-(@=) :: Wrapper h => FieldName k -> Repr h v -> Field h (k ':> v)+(@=) :: Wrapper h => Proxy k -> Repr h v -> Field h (k ':> v) (@=) _ = Field #. review _Wrapper {-# INLINE (@=) #-} infix 1 @=@@ -288,18 +270,18 @@ -- <: #str \<\@=\> getLine -- <: nil -- @-(<@=>) :: (Functor f, Wrapper h) => FieldName k -> f (Repr h v) -> Compose f (Field h) (k ':> v)+(<@=>) :: (Functor f, Wrapper h) => Proxy k -> f (Repr h v) -> Compose f (Field h) (k ':> v) (<@=>) k = comp (k @=) {-# INLINE (<@=>) #-} infix 1 <@=> -- | Annotate a value by the field name without 'Wrapper'.-(@:>) :: FieldName k -> h v -> Field h (k ':> v)+(@:>) :: Proxy k -> h v -> Field h (k ':> v) (@:>) _ = Field infix 1 @:> -- | Kind-monomorphic, unwrapped version of '@='-(@==) :: FieldName (k :: Symbol) -> v -> Field Identity (k ':> v)+(@==) :: Proxy (k :: Symbol) -> v -> Field Identity (k ':> v) (@==) = (@=) {-# INLINE (@==) #-} infix 1 @==
src/Data/Extensible/Label.hs view
@@ -10,26 +10,16 @@ -- -- Experimental API for OverloadedLabels. GHC 8.0+ only ------------------------------------------------------------------------------module Data.Extensible.Label where+module Data.Extensible.Label () where import Data.Extensible.Class import Data.Extensible.Field-import Data.Extensible.Product (hlookup) import Data.Proxy import GHC.OverloadedLabels-import GHC.Records import Data.Extensible.Wrapper -instance k ~ l => IsLabel k (Proxy l) where- fromLabel = Proxy---- | Specialised version of 'itemAssoc'. Stands for "eXtensible LaBel"-xlb :: Proxy k -> FieldOptic k-xlb t = itemAssoc t- instance (Extensible f p e , Lookup xs k v- , Labelling k p , Wrapper h , ExtensibleConstr e xs (Field h) (k ':> v) , rep ~ Repr h v@@ -39,6 +29,3 @@ ) => IsLabel k (p rep (f rep') -> p s (f t)) where fromLabel = itemAssoc (Proxy :: Proxy k)--instance (Lookup xs k v, Wrapper h, Repr h v ~ a) => HasField k (RecordOf h xs) a where- getField = unwrap . hlookup (association :: Membership xs (k >: v))
src/Data/Extensible/TH.hs view
@@ -29,8 +29,10 @@ -- @ -- mkField :: String -> DecsQ-mkField str = fmap concat $ forM (words str) $ \s@(x:xs) ->- let name = mkName $ if isLower x then x : xs else '_' : x : xs+mkField str = fmap concat $ forM (words str) $ \s ->+ let name = mkName $ case s of+ x : xs -> if isLower x then x : xs else '_' : x : xs+ _ -> error "Impossible" in mkFieldAs name s -- | @'mkFieldAs' (mkName "foo") "bar"@ defines a field for "bar" as @foo@.
src/Data/Extensible/Tangle.hs view
@@ -23,11 +23,11 @@ import Control.Monad.Trans.Class import Data.Functor.Compose import Data.Extensible.Class-import Data.Extensible.Field import Data.Extensible.Product import Data.Extensible.Internal.Rig import Data.Extensible.Nullable import Data.Extensible.Wrapper+import Data.Proxy -- | @'TangleT' h xs m@ is the monad of computations that may depend on the elements in 'xs'. newtype TangleT xs h m a = TangleT@@ -46,7 +46,7 @@ -- | Hitch an element associated to the 'FieldName' through a wrapper. lasso :: forall k v m h xs. (Monad m, Lookup xs k v, Wrapper h)- => FieldName k -> TangleT xs h m (Repr h (k ':> v))+ => Proxy k -> TangleT xs h m (Repr h (k ':> v)) lasso _ = view _Wrapper <$> hitchAt (association :: Membership xs (k ':> v)) {-# INLINE lasso #-}