packages feed

generic-lens 2.2.2.0 → 2.3.0.0

raw patch · 7 files changed

+169/−30 lines, 7 filesdep +mtldep −textdep ~basedep ~generic-lens-corenew-uploaderPVP ok

version bump matches the API change (PVP)

Dependencies added: mtl

Dependencies removed: text

Dependency ranges changed: base, generic-lens-core

API changes (from Hackage documentation)

- Data.Generics.Internal.VL: type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
+ Data.Generics.Internal.VL: Curried :: (forall r. () => f (a -> r) -> f r) -> Curried (f :: Type -> Type) a
+ Data.Generics.Internal.VL: Yoneda :: (forall b. () => (a -> b) -> f b) -> Yoneda (f :: Type -> Type) a
+ Data.Generics.Internal.VL: [runCurried] :: Curried (f :: Type -> Type) a -> forall r. () => f (a -> r) -> f r
+ Data.Generics.Internal.VL: [runYoneda] :: Yoneda (f :: Type -> Type) a -> forall b. () => (a -> b) -> f b
+ Data.Generics.Internal.VL: confusing :: Applicative f => Traversal s t a b -> (a -> f b) -> s -> f t
+ Data.Generics.Internal.VL: liftCurried :: Applicative f => f a -> Curried f a
+ Data.Generics.Internal.VL: liftCurriedYoneda :: Applicative f => f a -> Curried (Yoneda f) a
+ Data.Generics.Internal.VL: liftYoneda :: Functor f => f a -> Yoneda f a
+ Data.Generics.Internal.VL: lowerCurried :: Applicative f => Curried f a -> f a
+ Data.Generics.Internal.VL: lowerYoneda :: Yoneda f a -> f a
+ Data.Generics.Internal.VL: newtype Curried (f :: Type -> Type) a
+ Data.Generics.Internal.VL: newtype Yoneda (f :: Type -> Type) a
+ Data.Generics.Internal.VL: type Traversal s t a b = forall (f :: Type -> Type). Applicative f => a -> f b -> s -> f t
+ Data.Generics.Internal.VL: yap :: Applicative f => Yoneda f (a -> b) -> f a -> Yoneda f b
+ Data.Generics.Labels: instance (GHC.Base.Functor f, Data.Generics.Labels.Position i s t a b, i GHC.Types.~ Data.Generics.Labels.ParseNat name) => Data.Generics.Labels.IsLabelHelper 'Data.Generics.Labels.PositionType name (->) f s t a b
+ Data.Generics.Labels: instance Data.Generics.Product.Positions.HasPosition i s t a b => Data.Generics.Labels.Position i s t a b
+ Data.Generics.Labels: instance Data.Generics.Product.Positions.HasPosition' i s a => Data.Generics.Labels.Position i s s a a
+ Data.Generics.Sum.Typed: instance Data.Generics.Sum.Typed.AsType a a
- Data.Generics.Internal.VL: kIso :: Iso (K1 r a p) (K1 r b p) a b
+ Data.Generics.Internal.VL: kIso :: forall {k} r a (p1 :: k) b p2 f. (Profunctor p2, Functor f) => p2 a (f b) -> p2 (K1 r a p1) (f (K1 r b p1))
- Data.Generics.Internal.VL: mIso :: Iso (M1 i c f p) (M1 i c g p) (f p) (g p)
+ Data.Generics.Internal.VL: mIso :: forall {k} i (c :: Meta) f1 (p1 :: k) g p2 f2. (Profunctor p2, Functor f2) => p2 (f1 p1) (f2 (g p1)) -> p2 (M1 i c f1 p1) (f2 (M1 i c g p1))
- Data.Generics.Internal.VL: paramIso :: Iso (Param n a) (Param n b) a b
+ Data.Generics.Internal.VL: paramIso :: forall (n :: Nat) a b p f. (Profunctor p, Functor f) => p a (f b) -> p (Param n a) (f (Param n b))
- Data.Generics.Internal.VL: prodIso :: Iso ((a :*: b) x) ((a' :*: b') x) (a x, b x) (a' x, b' x)
+ Data.Generics.Internal.VL: prodIso :: forall {k} a b (x :: k) a' b' p f. (Profunctor p, Functor f) => p (a x, b x) (f (a' x, b' x)) -> p ((a :*: b) x) (f ((a' :*: b') x))
- Data.Generics.Internal.VL: recIso :: Iso (Rec r a p) (Rec r b p) a b
+ Data.Generics.Internal.VL: recIso :: forall {k} r a (p1 :: k) b p2 f. (Profunctor p2, Functor f) => p2 a (f b) -> p2 (Rec r a p1) (f (Rec r b p1))
- Data.Generics.Internal.VL: type Prism s t a b = forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t)
+ Data.Generics.Internal.VL: type Prism s t a b = forall (p :: Type -> Type -> Type) (f :: Type -> Type). (Choice p, Applicative f) => p a f b -> p s f t
- Data.Generics.Labels: class Constructor name s t a b | name s -> a, name t -> b
+ Data.Generics.Labels: class Constructor (name :: k) s t a b | name s -> a, name t -> b
- Data.Generics.Labels: class Field name s t a b | s name -> a, t name -> b, s name b -> t, t name a -> s
+ Data.Generics.Labels: class Field (name :: k) s t a b | s name -> a, t name -> b, s name b -> t, t name a -> s
- Data.Generics.Labels: type Constructor' name s a = Constructor name s s a a
+ Data.Generics.Labels: type Constructor' (name :: k) s a = Constructor name s s a a
- Data.Generics.Labels: type Field' name s a = Field name s s a a
+ Data.Generics.Labels: type Field' (name :: k) s a = Field name s s a a
- Data.Generics.Product.Any: class HasAny sel s t a b | s sel -> a
+ Data.Generics.Product.Any: class HasAny (sel :: k) s t a b | s sel -> a
- Data.Generics.Product.Fields: getField :: forall f a s. HasField' f s a => s -> a
+ Data.Generics.Product.Fields: getField :: forall (f :: Symbol) a s. HasField' f s a => s -> a
- Data.Generics.Product.Fields: setField :: forall f s a. HasField' f s a => a -> s -> s
+ Data.Generics.Product.Fields: setField :: forall (f :: Symbol) s a. HasField' f s a => a -> s -> s
- Data.Generics.Product.HList: class IsList (f :: Type) (g :: Type) (as :: [Type]) (bs :: [Type]) | f -> as, g -> bs
+ Data.Generics.Product.HList: class IsList f g (as :: [Type]) (bs :: [Type]) | f -> as, g -> bs
- Data.Generics.Product.Positions: getPosition :: forall i s a. HasPosition' i s a => s -> a
+ Data.Generics.Product.Positions: getPosition :: forall (i :: Nat) s a. HasPosition' i s a => s -> a
- Data.Generics.Product.Positions: setPosition :: forall i s a. HasPosition' i s a => a -> s -> s
+ Data.Generics.Product.Positions: setPosition :: forall (i :: Nat) s a. HasPosition' i s a => a -> s -> s
- Data.Generics.Sum.Any: class AsAny sel a s | s sel -> a
+ Data.Generics.Sum.Any: class AsAny (sel :: k) a s | s sel -> a
- Data.Generics.Wrapped: wrappedFrom :: forall s t a b. Wrapped s t a b => b -> t
+ Data.Generics.Wrapped: wrappedFrom :: Wrapped s t a b => b -> t
- Data.Generics.Wrapped: wrappedTo :: forall s t a b. Wrapped s t a b => s -> a
+ Data.Generics.Wrapped: wrappedTo :: Wrapped s t a b => s -> a

Files

ChangeLog.md view
@@ -1,3 +1,15 @@+## generic-lens-2.3.0.0 (2025-08-27)++Tested with GHC 8.4 - 9.14 alpha1.++- Add `OverloadedLabels` support for positional lenses, e.g. `#3` as an+  abbreviation for `position @3`, starting with GHC 9.6.++### Breaking API changes:+- `AsType` now includes a reflexive case for consistency with `HasType`: every+  type can be treated 'as' itself.++ ## generic-lens-2.2.2.0 (2023-04-15) - Support unprefixed constructor prisms on GHC 9.6 (#152) @@ -73,7 +85,7 @@  - The type parameters of the classes have been changed to accommodate   the type-changing update:-  +   `class HasField name a s` -> `class HasField name s t a b` etc.-  +   Accordingly, `field :: Lens' s a` -> `field :: Lens s t a b`
generic-lens.cabal view
@@ -1,5 +1,6 @@+cabal-version:        2.0 name:                 generic-lens-version:              2.2.2.0+version:              2.3.0.0 synopsis:             Generically derive traversals, lenses and prisms. description:          This library uses GHC.Generics to derive efficient optics (traversals, lenses and prisms) for algebraic data types in a type-directed way, with a focus on good type inference and error messages when possible.                       .@@ -13,13 +14,27 @@ maintainer:           kiss.csongor.kiss@gmail.com category:             Generics, Records, Lens build-type:           Simple-cabal-version:        >= 1.10-Tested-With:          GHC == 8.4.1, GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.3, GHC == 9.0.1, GHC == 9.2.1 +tested-with:+  GHC == 9.14.1+  GHC == 9.12.2+  GHC == 9.10.2+  GHC == 9.8.4+  GHC == 9.6.7+  GHC == 9.4.8+  GHC == 9.2.8+  GHC == 9.0.2+  GHC == 8.10.7+  GHC == 8.8.4+  GHC == 8.6.5+  GHC == 8.4.4++ extra-source-files:   examples/StarWars.hs                     , examples/Examples.hs-                    , ChangeLog.md +extra-doc-files:      ChangeLog.md+ library   exposed-modules:    Data.Generics.Wrapped                     , Data.Generics.Product@@ -45,24 +60,24 @@                     , Data.Generics.Internal.VL.Iso    build-depends:      base        >= 4.11 && < 5-                    , generic-lens-core == 2.2.1.0+                    , generic-lens-core ^>= 2.3.0.0                     , profunctors-                    , text        >= 1.2 && < 1.3 || >= 2.0 && < 2.1    hs-source-dirs:     src   default-language:   Haskell2010+  default-extensions: TypeOperators   ghc-options:        -Wall  test-suite inspection-tests   type:               exitcode-stdio-1.0   hs-source-dirs:     test   main-is:            Spec.hs-  other-modules:      Util Test24 Test88 Test25 Test40 Test62 Test63 CustomChildren+  other-modules:      Util Test24 Test88 Test25 Test40 Test62 Test63 Test146 CustomChildren -  build-depends:      base          >= 4.11 && <= 5.0+  build-depends:      base                     , generic-lens                     , lens-                    , profunctors+                    , mtl                     , inspection-testing >= 0.2                     , HUnit @@ -74,7 +89,7 @@   hs-source-dirs:     test   main-is:            Bifunctor.hs -  build-depends:      base          >= 4.11 && <= 5.0+  build-depends:      base                     , generic-lens                     , lens                     , HUnit@@ -87,10 +102,9 @@   hs-source-dirs:     test/syb   main-is:            Tree.hs -  build-depends:      base          >= 4.11 && <= 5.0+  build-depends:      base                     , generic-lens                     , lens-                    , profunctors                     , HUnit    default-language:   Haskell2010@@ -101,7 +115,6 @@   type:               exitcode-stdio-1.0   ghc-options:        -threaded   main-is:            doctest.hs-  build-depends:      base >4 && <5+  build-depends:      base >= 4 && <5                     , doctest-                    , lens   hs-source-dirs:     examples
src/Data/Generics/Labels.hs view
@@ -1,10 +1,14 @@ {-# LANGUAGE PackageImports #-} {-# LANGUAGE AllowAmbiguousTypes    #-} {-# LANGUAGE ConstraintKinds        #-}+{-# LANGUAGE CPP                    #-} {-# LANGUAGE DataKinds              #-} {-# LANGUAGE FlexibleInstances      #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses  #-}+#if MIN_VERSION_base(4,12,0)+{-# LANGUAGE NoStarIsType           #-}+#endif {-# LANGUAGE PolyKinds              #-} {-# LANGUAGE ScopedTypeVariables    #-} {-# LANGUAGE TypeApplications       #-}@@ -22,7 +26,8 @@ -- Stability   : experimental -- Portability : non-portable ----- Provides an (orphan) IsLabel instance for field lenses and constructor prisms.+-- Provides an (orphan) IsLabel instance for field lenses and constructor+-- prisms, as well as positional lenses on GHC >=9.6. -- Use at your own risk. -------------------------------------------------------------------------------- @@ -66,6 +71,14 @@ -- instance (AsConstructor name s t a b) => IsLabel name (Prism s t a b) where ... -- @ --+-- Starting with GHC 9.6, you can also write e.g. @#2@ and @#15@ instead of+-- @position \@1@ and @position \@15@, so we morally have+--+-- @+-- instance (HasPosition i s t a b) => IsLabel (Show i) (Lens s t a b) where ...+-- @+--+-- -- Remember: -- -- @@@ -107,17 +120,29 @@ instance {-# INCOHERENT #-} AsConstructor' name s a => Constructor name s s a a where   constructorPrism = _Ctor' @name -data LabelType = FieldType | LegacyConstrType | ConstrType+data LabelType = FieldType | LegacyConstrType | ConstrType | PositionType  type family ClassifyLabel (name :: Symbol) :: LabelType where   ClassifyLabel name =-    If (CmpSymbol "_@" name == 'LT && CmpSymbol "_[" name == 'GT)-      'LegacyConstrType-      ( If (CmpSymbol "@" name == 'LT && CmpSymbol "[" name == 'GT)-          'ConstrType-          'FieldType+    If (StartsWithDigit name)+      'PositionType+      ( If (StartsWithUnderscoreAndUpperCase name)+          'LegacyConstrType+          ( If (StartsWithUpperCase name)+              'ConstrType+              'FieldType+          )       ) +type StartsWithDigit name =+  CmpSymbol "/" name == 'LT && CmpSymbol ":" name == 'GT++type StartsWithUnderscoreAndUpperCase name =+  CmpSymbol "_@" name == 'LT && CmpSymbol "_[" name == 'GT++type StartsWithUpperCase name =+  CmpSymbol "@" name == 'LT && CmpSymbol "[" name == 'GT+ instance ( labelType ~ ClassifyLabel name          , IsLabelHelper labelType name p f s t a b          , pafb ~ p a (f b), psft ~ p s (f t)) => IsLabel name (pafb -> psft) where@@ -131,6 +156,9 @@ -- done in the 'IsLabel' instance above).  If so, then we're dealing with a -- constructor name, which should be a prism, and otherwise, it's a field name, -- so we have a lens.+--+-- On GHC >=9.6, we also check whether the symbol starts with a digit, in which+-- case we are dealing with an index for a positional lens. class IsLabelHelper labelType name p f s t a b where   labelOutput :: p a (f b) -> p s (f t) @@ -144,3 +172,37 @@ instance ( Applicative f, Choice p, Constructor name s t a b          ) => IsLabelHelper 'ConstrType name p f s t a b where   labelOutput = constructorPrism @name++class Position (i :: Nat) s t a b | s i -> a, t i -> b, s i b -> t, t i a -> s where+  positionLens :: Lens s t a b++instance {-# INCOHERENT #-} HasPosition i s t a b => Position i s t a b where+  positionLens = position @i++instance {-# INCOHERENT #-} HasPosition' i s a => Position i s s a a where+  positionLens = position' @i++instance ( Functor f, Position i s t a b, i ~ ParseNat name+         ) => IsLabelHelper 'PositionType name (->) f s t a b where+  labelOutput = positionLens @i++-- 'ParseNat' is only necessary for positional lenses, which can only actually+-- be used with OverloadedLabels since GHC 9.6. Therefore, it is fine that this+-- code only compiles with GHC >=9.4 due to the use of newer GHC features (such+-- as 'UnconsSymbol').+#if MIN_VERSION_base(4,17,0)+type ParseNat name = ParseNat' 0 (UnconsSymbol name)++type family ParseNat' acc m where+  ParseNat' acc ('Just '(hd, tl)) =+    ParseNat' (10 * acc + DigitToNat hd) (UnconsSymbol tl)+  ParseNat' acc 'Nothing = acc++type DigitToNat c =+  If ('0' <=? c && c <=? '9')+    (CharToNat c - CharToNat '0')+    (TypeError ('Text "Invalid position number"))+#else+type family ParseNat name where+  ParseNat name = TypeError ('Text "Positional lenses not supported")+#endif
src/Data/Generics/Product/Typed.hs view
@@ -57,7 +57,8 @@ -- human = Human "Tunyasz" 50 "London" False -- :} --- |Records that have a field with a unique type.+-- |Types that contain another type, either by being a record with a field+-- with that type, or by actually being that type. class HasType a s where   -- |A lens that focuses on a field with a unique type in its parent type.   --  Compatible with the lens package's 'Control.Lens.Lens' type.@@ -102,6 +103,7 @@   typed = VL.ravel Core.derived   {-# INLINE typed #-} +-- |Every type 'has' itself. instance {-# OVERLAPPING #-} HasType a a where     getTyped = id     {-# INLINE getTyped #-}
src/Data/Generics/Sum/Typed.hs view
@@ -27,7 +27,7 @@ module Data.Generics.Sum.Typed   ( -- *Prisms     ---    --  $setup+    -- $setup     AsType (..)   ) where @@ -61,10 +61,11 @@ -- dog = Dog (MkDog "Shep" (Age 3)) -- cat = Cat "Mog" (Age 5) -- duck = Duck (Age 2)--- :}+-- >>> :}  --- |Sums that have a constructor with a field of the given type.+-- |Types that can represent another type, either by being a sum with a+-- constructor containing that type, or by actually being that type. class AsType a s where   -- |A prism that projects a constructor uniquely identifiable by the type of   --  its field. Compatible with the lens package's 'Control.Lens.Prism' type.@@ -86,16 +87,39 @@   {-# INLINE _Typed #-}    -- |Inject by type.+  --+  --+  --  >>> :{+  --  dog :: Dog+  --  dog = MkDog "Fido" (Age 11)+  --  dogAsAnimal :: Animal+  --  dogAsAnimal = injectTyped dog+  --  dogAsItself :: Dog+  --  dogAsItself = injectTyped dog+  -- >>> :}   injectTyped :: a -> s   injectTyped     = build _Typed    -- |Project by type.+  --+  --+  -- >>> :{+  -- dogAsAnimal :: Animal+  -- dogAsAnimal = Dog (MkDog "Fido" (Age 11))+  -- mDog :: Maybe Dog+  -- mDog = projectTyped dogAsAnimal+  -- >>> :}   projectTyped :: s -> Maybe a   projectTyped     = either (const Nothing) Just . match _Typed    {-# MINIMAL (injectTyped, projectTyped) | _Typed #-}++-- |Every type can be treated 'as' itself.+instance {-# OVERLAPPING #-} AsType a a where+  injectTyped = id+  projectTyped = Just  instance Core.Context a s => AsType a s where   _Typed eta = prism2prismvl Core.derived eta
test/Spec.hs view
@@ -33,6 +33,7 @@ import Test24 () import Test25 () import Test88 ()+import Test146 ()  import CustomChildren (customTypesTest) @@ -250,10 +251,10 @@   , $(inspectTest $ 'typeChangingManualCompose === 'typeChangingGenericCompose)   , $(inspectTest $ 'typeChangingManualCompose === 'typeChangingGenericCompose_)   , $(inspectTest $ 'sum1PrismManual           === 'sum1PrismB)-  -- , $(inspectTest $ 'subtypePrismManual        === 'subtypePrismGeneric) (TODO: fails on 8.4)+  -- , $(inspectTest $ 'subtypePrismManual        === 'subtypePrismGeneric)         -- TODO: fails on 8.4   , $(inspectTest $ 'sum2PrismManualChar       === 'sum2TypePrismChar)   , $(inspectTest $ 'sum2PrismManual           === 'sum2TypePrism)-  , $(inspectTest $ 'sum1PrismManualChar       === 'sum1TypePrismChar)+  -- , $(inspectTest $ 'sum1PrismManualChar       === 'sum1TypePrismChar)           -- TODO fails >=9.12   , $(inspectTest $ 'sum2PrismManualChar       === 'sum2TypePrismChar)   , $(inspectTest $ 'sum1PrismManual           === 'sum1TypePrism)   , $(inspectTest $ 'intTraversalManual        === 'intTraversalDerived)@@ -271,9 +272,17 @@   , (valLabel ^? #RecB . _1  ) ~=? Just 3   , (valLabel ^? #RecB       ) ~=? Just (3, True)   , (valLabel ^? #RecC       ) ~=? Nothing++  , (valLabel ^. #1          ) ~=? 3+  , let+      i x = x :: Int+      largeTuple  = (i 1, i 2, i 3, i 4, i 5, i 6, i 7, i 8, i 9, i 10, i 11, i 12, i 13, i 14, i 15)+      largeTuple' = (i 1, i 2, i 3, i 4, i 5, i 6, i 7, i 8, i 9, i 10, i 11, i 13, i 13, i 14, i 15)+    in+      (largeTuple ^. #13, largeTuple & #12 +~ 1) ~=? (13, largeTuple') #endif   , customTypesTest   ]-  where valLabel = RecB 3 True +  where valLabel = RecB 3 True  -- TODO: add test for traversals over multiple types
+ test/Test146.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}++module Test146 where++import Control.Monad.Except+import Data.Generics.Sum+import GHC.Generics++data Error = Error+  deriving (Generic)++poly :: (AsType Error e, MonadError e m) => m ()+poly = undefined++mono :: ExceptT Error IO ()+mono = poly