Search code examples
haskelllenseshaskell-lens

"Illegal polymorphic or qualified type" in Control.Lens


I'm working with Control.Lens. The actual function I'm writing is rather complex, but for the purpose of this question, I've boiled it down to a minimal failing example:

import Control.Lens    

exampleFunc :: Lens s t a b -> String
exampleFunc _ = "Example"

This fails to compile, yielding the following error message:

Illegal polymorphic or qualified type: Lens s t a b
Perhaps you intended to use -XRankNTypes or -XRank2Types
In the type signature for `exampleFunc':
  exampleFunc :: Lens s t a b -> String

Why is this illegal? It seems awfully similar to the following, which does compile:

import Data.Maybe

exampleFunc' :: Maybe (s, t, a, b) -> String
exampleFunc' _ = "Example"

So I'm assuming the difference lies in the definition of Lens. But what about the Lens type makes exampleFunc's type illegal? I have a sneaking suspicion it has to do with the Functor qualification in the definition of Lens, but I could be wrong. For reference, the definition of Lens is:

type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t

So, do I have to somehow satisfy the Functor qualification in my definition of exampleFunc? If so, how? I'm not seeing where in my type signature I have the opportunity to declare this constraint. Or maybe I'm on the wrong track, and my problem has nothing to do with the Functor constraint.

I've read all the Stack Overflow questions I could find regarding the "illegal polymorphic etc" error message. Perhaps this is my lack of familiarity with Haskell showing, but I can't see any of those questions being applicable to my current situation.

Nor have I been able to find any documentation on what the error message means in general.


Solution

  • Lens uses rank 2 types and you have it to the left of an arrow so to use any of lenses types like this you have to make it legal to even utter something like

    (forall a. foo) -> bar
    

    Which you can too with

    {-# LANGUAGE RankNTypes #-} -- Rank2Types is a synonym for RankNTypes
    

    at the top of your file. Without it, it's illegal to even use a lens type synonym since they use a part of the language you must enable.