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

Puzzling error message: No instance for ?Generic s? #160

Open
ddssff opened this issue Dec 17, 2023 · 1 comment
Open

Puzzling error message: No instance for ?Generic s? #160

ddssff opened this issue Dec 17, 2023 · 1 comment

Comments

@ddssff
Copy link

ddssff commented Dec 17, 2023

I sometimes get error messages that resemble GHC missing instance messages but I don't understand what they actually mean. For example, the declaration

import Control.Lens (ReifiedLens(Lens))
foo :: HasPosition i s t a b => ReifiedLens s t a b
foo = Lens (position0 @i)

Gives this error:

src/Data/Generics/Product/Positions.hs:109:18: error:
    * | No instance for ?Generic s?
      |   arising from a generic lens focusing on the field at
      |   position ?i? of type ?a? in ?s?
      
    * In the first argument of `Lens', namely `position0'
      In the expression: Lens (position0 @i)
      In an equation for `foo': foo = Lens (position0 @i)

Could someone explain what this question mark bracketing means? There is already a Generic constraint on s.

@aavogt
Copy link

aavogt commented Apr 27, 2024

generic lens core hardcodes unicode quotes, whereas ghc's own messages fall back to ascii.

If you're consistent with the 0 suffix it compiles:

{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
foo0 :: forall i s t a b. (HasPosition0 i s t a b) => ReifiedLens s t a b
foo0 = Lens (position0 @i)
foo :: forall i s t a b. (HasPosition i s t a b) => ReifiedLens s t a b
foo = Lens (position @i)

Adding a Generic s to fooErr's type signature confusingly has no effect on the error message.

fooErr :: forall i s t a b. (Generic s, HasPosition i s t a b) => ReifiedLens s t a b
fooErr = Lens (position0 @i)
{- main.hs:60:14: error: [GHC-64725]
    • | No instance for ‘Generic s’
      |   arising from a generic lens focusing on the field at
      |   position ‘i’ of type ‘a’ in ‘s’
      
    • In the first argument of ‘Lens’, namely ‘(position0 @i)’
      In the expression: Lens (position0 @i)
      In an equation for ‘fooErr’: fooErr = Lens (position0 @i)
-}

Instead of saying that the instance will always fix the problem, type family NoGeneric could instead make a suggestion that usually works:

    • | Suggested fix: `deriving instance Generic s'
      |   to satisfy a generic lens focusing on the field at
      |   position ‘i’ of type ‘a’ in ‘s’
      
    • In the first argument of ‘Lens’, namely ‘(position0 @i)’
      In the expression: Lens (position0 @i)
      In an equation for ‘fooErr’: fooErr = Lens (position0 @i)

The original message is slightly better in that it doesn't suggest an unnecessary -XStandaloneDeriving.

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

No branches or pull requests

2 participants