Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

LensFor: Couldn't match expected type p #659

Closed
yaitskov opened this issue Jan 12, 2023 · 7 comments
Closed

LensFor: Couldn't match expected type p #659

yaitskov opened this issue Jan 12, 2023 · 7 comments
Labels

Comments

@yaitskov
Copy link

yaitskov commented Jan 12, 2023

After upgrading GHC version from 8.10.7 to 9.2.4 following snippets fails:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# OPTIONS_GHC -fplugin=Polysemy.Plugin #-}

module Foo where

data Foo f = Foo  { fooInt :: C f Int }  deriving (Generic, Beamable)

module Bar where
{-# LANGUAGE ImpredicativeTypes #-}
{-# OPTIONS_GHC -Wno-missing-signatures #-}

import Database.Beam (LensFor (LensFor), TableLens (TableLens), dbLenses, tableLenses)
import Foo

Foo  (LensFor x)  = tableLenses

Couldn't match expected type ‘p’
              with actual type ‘microlens-0.4.12.0:Lens.Micro.Type.Lens'
                                  (Foo f1)
                                  (Database.Beam.Schema.Tables.Columnar
                                     f1 ghc-prim-0.8.0:GHC.Types.Int)’
  Cannot equate type variable ‘p’
  with a type involving polytypes:
    microlens-0.4.12.0:Lens.Micro.Type.Lens'
      (Foo f1)
      (Database.Beam.Schema.Tables.Columnar
         f1 ghc-prim-0.8.0:GHC.Types.Int)
  ‘p’ is a rigid type variable bound by
    the inferred type of x :: p
    at /home/dan/pro/Bar.hs:10:1-29
• In the pattern: LensFor x
  In the pattern: Foo (LensFor x)
  In a pattern binding: Foo (LensFor x) = tableLensestypecheck(-Wdeferred-type-errors)
@yaitskov yaitskov changed the title LenseFor LensFor: Couldn't match expected type p Jan 12, 2023
@yaitskov
Copy link
Author

I figured out how to define lenses manually as a workaround:

fooName ::
  forall (f1 :: Type -> Type) (f2 :: Type -> Type).
  Functor f2 =>
  (Columnar f1 Text -> f2 (Columnar f1 Text)) -> FooT f1 -> f2 (FooT f1)
fooName fa u = (\x -> u { _name = x } ) <$> fa (_name u)

@peterbecich
Copy link
Contributor

I have also seen this here which uses GHC 9.2: #650
The errors can be seen with nix-build release.nix


@gelisam helpfully directed me to look more closely at the ImpredicativeTypes extension.

The snippets rely on it:

!!! note "Note"
The `ImpredicativeTypes` language extension is necessary for newer
GHC to allow the polymorphically typed lenses to be introduced at
the top-level. Older GHCs were more lenient.

This says ImpredicativeTypes was unreliable before GHC 9.2: https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/impredicative_types.html
Now perhaps the extension has changed?

@berberman
Copy link

berberman commented Mar 22, 2023

I hit the same issue at 9.2.7. Writing the type signature by hand still (with NoMonomorphismRestriction enabled) doesn't work. I tried fooName :: forall f. Functor f => Lens' (FooT f) (C f Text), though it compiles, but at the use site there is an error No instance for (Functor ...). I also tried expanding Lens' further: fooName :: forall f1 f2. Functor f2 => (C f1 Text -> f2 (C f1 Text)) -> FooT f1 -> f2 (FooT f1), but this doesn't compile due to Could not deduce (Functor f1) arising from GHC Bug #20076.

@arguri
Copy link

arguri commented Mar 24, 2023

@berberman and @yaitskov

Have you tried

Module Foo where 

import Database.Beam 
import Lens.Micro 

data FooT f = Foo  { _fooInt :: C f Int }  deriving (Generic, Beamable)
type Foo = FooT Identity 

fooName :: Lens Foo Foo Int Int 
Foo  (LensFor fooName)  = tableLenses

@yaitskov
Copy link
Author

@arguri, it only works for data with 1 field (i.e. newtype)

• Could not deduce (Functor f0) arising from GHC Bug #20076
  from the context: Functor f
    bound by the inferred type for ‘projectName’:
               Lens HackageProject HackageProject Text Text
    at /home/dan/pro/Tables/HackageProject.hs:42:1-71
  The type variable ‘f0’ is ambiguous
  These potential instances exist:
    instance Functor (Either a) -- Defined in ‘Data.Either’
    instance Functor Identity -- Defined in ‘Data.Functor.Identity’
    instance Functor (With be db)
      -- Defined in ‘Database.Beam.Query.CTE’
    ...plus 9 others
    ...plus 281 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
• When checking that the inferred type
    projectName :: forall {f1 :: * -> *} {f2 :: * -> *}.
                   (Functor f1, Functor f2) =>
                   (Text -> f1 Text) -> HackageProject -> f1 HackageProject
  is as general as its signature
    projectName :: Lens HackageProject HackageProject Text Text

@arguri
Copy link

arguri commented Apr 15, 2023

@yaitskov

For more fields you would need to add Signatures for each field and ignore the other fields, e.g.

module Foo where 

import Database.Beam 
import Lens.Micro 

data Foo { fooName :: C f Int, fooId :: C f String } deriving (Generic, Beamable)

fooName :: Lens Foo Foo Int Int 
fooId :: Lens Foo Foo String String 
Foo (LensFor fooName) _ = tableLenses 
Foo _ (LensFor fooId) = tableLenses 

At least that worked for me.

@yaitskov
Copy link
Author

yaitskov commented May 6, 2023

Thanks, I see - every lens binding should have dedicated expression and they cannot be batched in one data constructor.

@haskell-beam haskell-beam locked and limited conversation to collaborators Jun 8, 2024
@kmicklas kmicklas converted this issue into discussion #713 Jun 8, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Projects
None yet
Development

No branches or pull requests

5 participants