Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"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.

like image 804
rlkw1024 Avatar asked Nov 20 '13 19:11

rlkw1024


1 Answers

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.

like image 73
Daniel Gratzer Avatar answered Oct 19 '22 20:10

Daniel Gratzer