Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

makeLenses regression in lens-5 #972

Closed
RyanGlScott opened this issue Feb 24, 2021 · 1 comment · Fixed by #973
Closed

makeLenses regression in lens-5 #972

RyanGlScott opened this issue Feb 24, 2021 · 1 comment · Fixed by #973

Comments

@RyanGlScott
Copy link
Collaborator

The following code, minimized from the hgeometry-combinatorial-0.11.0.0 library, compiles successfully with lens-4.19.2:

{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -ddump-splices #-}
module Bug where

import Control.Lens

newtype Arc s = Arc { _unArc :: Int }

data Direction = Negative | Positive
data Dart s = Dart { _arc :: Arc s, _direction :: Direction }
$(makeLenses ''Dart)

However, it fails to compile with lens-5:

[1 of 1] Compiling Bug              ( Bug.hs, interpreted )
Bug.hs:12:3-19: Splicing declarations
    makeLenses ''Dart
  ======>
    arc ::
      forall k_a546 (s_a53w :: k_a546) k_a54D (s_a54C :: k_a54D).
      Lens (Dart (s_a53w :: k_a546)) (Dart (s_a54C :: k_a54D)) (Arc s_a53w) (Arc s_a54C)
    arc f_a54F (Dart x1_a54G x2_a54H)
      = (fmap (\ y1_a54I -> (Dart y1_a54I) x2_a54H)) (f_a54F x1_a54G)
    {-# INLINE arc #-}
    direction ::
      forall k_a546 (s_a53w :: k_a546) k_a54E.
      Lens (Dart (s_a53w :: k_a546)) (Dart (s_a53w :: k_a54E)) Direction Direction
    direction f_a54J (Dart x1_a54K x2_a54L)
      = (fmap (\ y1_a54M -> (Dart x1_a54K) y1_a54M)) (f_a54J x2_a54L)
    {-# INLINE direction #-}

Bug.hs:12:3: error:
    • Expected kind ‘k1’, but ‘s_a53w’ has kind ‘k0’
    • In the first argument of ‘Dart’, namely ‘(s_a53w :: k_a54E)’
      In the second argument of ‘Lens’, namely
        ‘(Dart (s_a53w :: k_a54E))’
      In the type signature:
        direction :: forall k_a546 (s_a53w :: k_a546) k_a54E.
                     Lens (Dart (s_a53w :: k_a546)) (Dart (s_a53w :: k_a54E)) Direction Direction
   |
12 | $(makeLenses ''Dart)
   |   ^^^^^^^^^^^^^^^^^

Bug.hs:12:3: error:
    • Couldn't match type ‘k’ with ‘k1’
      ‘k’ is a rigid type variable bound by
        the type signature for:
          direction :: forall k (s :: k) k2.
                       Lens (Dart s) (Dart s) Direction Direction
        at Bug.hs:12:3-19
      ‘k1’ is a rigid type variable bound by
        the type signature for:
          direction :: forall k (s :: k) k2.
                       Lens (Dart s) (Dart s) Direction Direction
        at Bug.hs:12:3-19
      Expected type: f (Dart @{k1} s)
        Actual type: f (Dart @{k} s)
    • In the expression:
        (fmap (\ y1_a54M -> (Dart x1_a54K) y1_a54M)) (f_a54J x2_a54L)
      In an equation for ‘direction’:
          direction f_a54J (Dart x1_a54K x2_a54L)
            = (fmap (\ y1_a54M -> (Dart x1_a54K) y1_a54M)) (f_a54J x2_a54L)
    • Relevant bindings include
        x1_a54K :: Arc s (bound at Bug.hs:12:3)
        direction :: (Direction -> f Direction) -> Dart s -> f (Dart s)
          (bound at Bug.hs:12:3)
   |
12 | $(makeLenses ''Dart)
   |   ^^^^^^^^^^^^^^^^^

The immediate culprit is the type that lens generates for direction, as shown in the -ddump-splices output above:

    direction ::
      forall k_a546 (s_a53w :: k_a546) k_a54E.
      Lens (Dart (s_a53w :: k_a546)) (Dart (s_a53w :: k_a54E)) Direction Direction

This has only one s type variable, s_a53w, but it attempts to give it two different kinds, k_a546 and k_a54E.

RyanGlScott added a commit that referenced this issue Feb 24, 2021
Previously, `buildStab` would not consider kind variables when determining
which type variables need to be fixed in a generated `Lens`'s type signature.
This was not a problem in older versions of `lens`, which aggressively dropped
kind variables, but now that `lens` attempts to include kind variables in
generated type signatures, this problem has risen to the surface, resulting in
the problems observed in #972.

The solution is to take the set of fixed type variables in `buildStab` and
close over kind variables. For more information, refer to the comments I have
left near `closeOverKinds`.

Fixes #972.
RyanGlScott added a commit that referenced this issue Feb 24, 2021
Previously, `buildStab` would not consider kind variables when determining
which type variables need to be fixed in a generated `Lens`'s type signature.
This was not a problem in older versions of `lens`, which aggressively dropped
kind variables, but now that `lens` attempts to include kind variables in
generated type signatures, this problem has risen to the surface, resulting in
the problems observed in #972.

The solution is to take the set of fixed type variables in `buildStab` and
close over kind variables. For more information, refer to the comments I have
left near `closeOverKinds`.

Fixes #972.
@RyanGlScott
Copy link
Collaborator Author

See #973 for a fix.

RyanGlScott added a commit that referenced this issue Feb 24, 2021
Previously, `buildStab` would not consider kind variables when determining
which type variables need to be fixed in a generated `Lens`'s type signature.
This was not a problem in older versions of `lens`, which aggressively dropped
kind variables, but now that `lens` attempts to include kind variables in
generated type signatures, this problem has risen to the surface, resulting in
the problems observed in #972.

The solution is to take the set of fixed type variables in `buildStab` and
close over kind variables. For more information, refer to the comments I have
left near `closeOverKinds`.

Fixes #972.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant