Search code examples
haskellhaskell-lens

How to avoid the warning "Redundant constraint: Functor f" in the getter?


I have some record SomeRecord and fields like _user, _password. And I want to write a Getter for a "virtual" field, like identity which will look like <user>:<password>:

identity:: Getter SomeRecord String
identity = to $ \srec -> srec^.user <> ":" <> srec^.password

and this getter leads to the warning:

• Redundant constraint: Functor f
• In the type signature for:
       identity :: Getter SomeRecord Stringtypecheck(-Wredundant-constraints)

what's wrong with this getter and how to write it without warnings?

EDIT:

Just found this thread in the Web:

Comment (by ekmett):

In the interest of not getting drowned in complaints by the users of lens on GHC 8, we'll likely just add the constraint to to and rely on {-# INLINE #-} dropping it out in practice. This is a common enough scenario to warrant us eating the noise on our side.

Of course, you'll get the same sort of thing if you go to declare a non- law abiding traversal as a fold, etc. There i'm afraid the only answer will be to squelch the warning. GHC can't see 'laws'.


Solution

  • This is due to the way that Edward Kmett's lens library works.

    Getter is a type synonym:

    type Getter s a = forall f. (Contravariant f, Functor f) => (a -> f a) -> s -> f s
    

    Meanwhile the type of to is:

    to :: (Profunctor p, Contravariant f) => (s -> a) -> Optic' p f s a
    

    Never mind the Optic', the problem is that Getter has the constraint Functor f but the to doesn't need it. Hence the warning, because otherwise you could use it with a type f that isn't a functor.

    The "proper" type for your function is something like:

    identity :: (Profunctor p, Contravariant f) => Optic' p f SomeRecord String