eve icon indicating copy to clipboard operation
eve copied to clipboard

Proposed solution to type mismatch for makeStateLens in lts-19.19 (GHC 9.0.2)

Open xogcox opened this issue 3 years ago • 0 comments

I tried compiling on Stackage lts-19.19, and found the following type error for makeStateLens:

    • Couldn't match type: a0 -> a1 -> f0 a1
                     with: forall (f :: * -> *).
                           Functor f =>
                           (a -> f a) -> myState -> f myState
      Expected: Lens' myState a -> Lens' s a
        Actual: (a0 -> a1 -> f0 a1) -> a0 -> e0 -> f0 e0
    • In the expression: stateLens .
      In an equation for ‘makeStateLens’: makeStateLens = (stateLens .)

This seems to be very similar to the first of the errors in issue #6.

After playing with the types and looking up the recent changes to GHC, I found a way to resolve this error. It seems that the cause is that GHC >=9.0 has more restrictive conditions for matching non-top-level forall, as documented in the section on "Subsumption" in the GHC User's Guide.

This documentation says that the error can be resolved by eta-expansion; that is, change the function definition from point-free style:

makeStateLens = (stateLens .)

to pointful style:

makeStateLens x = (stateLens .) x

I tried this and it works. The good news is that there were no other errors compiling with lts-19.19 (GHC 9.0.2). (There was one warning -- that in src/Eve/Internal/Actions.hs, the import of 'Data.Semigroup' is redundant.) Would a pull request be useful? The only edit required is the one-line change to makeStateLens shown above.

Apparently eta-expansion may degrade performance in some cases. However, there is probably no other easy solution. Perhaps using some kind of type wrangling to convince the type checker would work, but I have no idea whether this is possible.

xogcox avatar Aug 20 '22 09:08 xogcox