lens 5 → 5.0.1
raw patch · 9 files changed
+92/−11 lines, 9 filesdep ~base-compatdep ~call-stackdep ~hashable
Dependency ranges changed: base-compat, call-stack, hashable
Files
- CHANGELOG.markdown +5/−0
- cabal.project +4/−0
- examples/lens-examples.cabal +3/−2
- lens-properties/lens-properties.cabal +3/−2
- lens.cabal +5/−3
- src/Control/Lens/Internal/FieldTH.hs +46/−3
- tests/T917.hs +1/−1
- tests/T972.hs +24/−0
- tests/templates.hs +1/−0
CHANGELOG.markdown view
@@ -1,3 +1,8 @@+5.0.1 [2021.02.24]+------------------+* Fix a bug in which `makeLenses` could produce ill kinded optics for+ poly-kinded datatypes in certain situations.+ 5 [2021.02.17] -------------- * Support building with GHC 9.0.
cabal.project view
@@ -1,3 +1,7 @@ packages: . ./examples ./lens-properties++allow-newer:+ cassava:base,+ vector-binary-instances:base
examples/lens-examples.cabal view
@@ -22,8 +22,9 @@ , GHC == 8.2.2 , GHC == 8.4.4 , GHC == 8.6.5- , GHC == 8.8.3- , GHC == 8.10.1+ , GHC == 8.8.4+ , GHC == 8.10.4+ , GHC == 9.0.1 source-repository head type: git
lens-properties/lens-properties.cabal view
@@ -19,8 +19,9 @@ , GHC == 8.2.2 , GHC == 8.4.4 , GHC == 8.6.5- , GHC == 8.8.3- , GHC == 8.10.1+ , GHC == 8.8.4+ , GHC == 8.10.4+ , GHC == 9.0.1 extra-source-files: .hlint.yaml
lens.cabal view
@@ -1,6 +1,6 @@ name: lens category: Data, Lenses, Generics-version: 5+version: 5.0.1 license: BSD2 cabal-version: 1.18 license-file: LICENSE@@ -18,8 +18,9 @@ , GHC == 8.2.2 , GHC == 8.4.4 , GHC == 8.6.5- , GHC == 8.8.3- , GHC == 8.10.1+ , GHC == 8.8.4+ , GHC == 8.10.4+ , GHC == 9.0.1 synopsis: Lenses, Folds and Traversals description: This package comes \"Batteries Included\" with many useful lenses for the types@@ -346,6 +347,7 @@ other-modules: T799 T917+ T972 ghc-options: -Wall -threaded hs-source-dirs: tests default-language: Haskell2010
src/Control/Lens/Internal/FieldTH.hs view
@@ -49,7 +49,7 @@ import Language.Haskell.TH import qualified Language.Haskell.TH.Datatype as D import qualified Language.Haskell.TH.Datatype.TyVarBndr as D-import Data.Maybe (isJust,maybeToList)+import Data.Maybe (fromMaybe,isJust,maybeToList) import Data.List (nub, findIndices) import Data.Either (partitionEithers) import Data.Semigroup (Any (..))@@ -249,9 +249,52 @@ where (fixedFields, targetFields) = partitionEithers categorizedFields- fixedTypeVars = setOf typeVars fixedFields- unfixedTypeVars = setOf typeVars s Set.\\ fixedTypeVars + fixedTypeVars, unfixedTypeVars :: Set Name+ fixedTypeVars = closeOverKinds $ setOf typeVars fixedFields+ unfixedTypeVars = setOf typeVars s Set.\\ fixedTypeVars++ -- Compute the kind variables that appear in the kind of a type variable+ -- binder. For example, @kindVarsOfTvb (x :: (a, b)) = (x, {a, b})@. If a+ -- type variable binder lacks an explicit kind annotation, this+ -- conservatively assumes that there are no kind variables. For example,+ -- @kindVarsOfTvb (y) = (y, {})@.+ kindVarsOfTvb :: D.TyVarBndr_ flag -> (Name, Set Name)+ kindVarsOfTvb = D.elimTV (\n -> (n, Set.empty))+ (\n k -> (n, setOf typeVars k))++ -- For each type variable name that appears in @s@, map to the kind variables+ -- that appear in that type variable's kind.+ sKindVarMap :: Map Name (Set Name)+ sKindVarMap = Map.fromList $ map kindVarsOfTvb $ D.freeVariablesWellScoped [s]++ lookupSKindVars :: Name -> Set Name+ lookupSKindVars n = fromMaybe Set.empty $ Map.lookup n sKindVarMap++ -- Consider this example (adapted from #972):+ --+ -- data Dart (s :: k) = Dart { _arc :: Proxy s, _direction :: Int }+ -- $(makeLenses ''Dart)+ --+ -- When generating a Lens for `direction`, the type variable `s` should be+ -- fixed. But note that (s :: k), and as a result, the kind variable `k`+ -- needs to be fixed as well. This is because a type like this would be+ -- ill kinded:+ --+ -- direction :: Lens (Dart (s :: k1)) (Dart (s :: k2)) Direction Direction+ --+ -- However, only `s` is mentioned syntactically in the type of `_arc`, so we+ -- have to infer that `k` is mentioned in the kind of `s`. We accomplish this+ -- with `closeOverKinds`, which does the following:+ --+ -- 1. Use freeVariablesWellScoped to compute the free type variables of+ -- `Dart (s :: k)`, which gives us `(s :: k)`.+ -- 2. For each type variable name in `Proxy s`, the type of `_arc`, look up+ -- the kind variables in the type variable's kind. In the case of `s`,+ -- the only kind variable is `k`.+ -- 3. Add these kind variables to the set of fixed type variables.+ closeOverKinds :: Set Name -> Set Name+ closeOverKinds st = foldl' Set.union Set.empty (Set.map lookupSKindVars st) `Set.union` st -- | Build the signature and definition for a single field optic. -- In the case of a singleton constructor irrefutable matches are
tests/T917.hs view
@@ -18,7 +18,7 @@ import Data.Kind #endif --- Like Data.Functor.Const, but redfined to ensure that it is poly-kinded+-- Like Data.Functor.Const, but redefined to ensure that it is poly-kinded -- across all versions of GHC, not just 8.0+ newtype Constant a (b :: k) = Constant a
+ tests/T972.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE TemplateHaskell #-}++#if __GLASGOW_HASKELL__ >= 800 && __GLASGOW_HASKELL__ < 806+{-# LANGUAGE TypeInType #-}+#endif+module T972 where++import Control.Lens+#if __GLASGOW_HASKELL__ >= 800+import Data.Proxy+#endif++newtype Arc s = Arc { _unArc :: Int }++data Direction = Negative | Positive+data Dart s = Dart { _arc :: Arc s, _direction :: Direction }+$(makeLenses ''Dart)++#if __GLASGOW_HASKELL__ >= 800+data Fancy k (a :: k) = MkFancy { _unFancy1 :: k, _unFancy2 :: Proxy a }+$(makeLenses ''Fancy)+#endif
tests/templates.hs view
@@ -28,6 +28,7 @@ -- import Test.QuickCheck (quickCheck) import T799 () import T917 ()+import T972 () data Bar a b c = Bar { _baz :: (a, b) } makeLenses ''Bar