Reputation: 41909
Before getting to my question, let me state my understanding (perhaps incorrect) that a List []
is a higher-kinded type:
ghci> :kind []
[] :: * -> *
I could be mistaken, but, a []
needs a type since it's a List of some type 'T'
.
Now to my question.
class Foo a where
bar :: String -> a
Then, I try to create a Foo [String]
. My understanding is that the a
in Foo a
is [String]
. So, I'd expect bar
to return a [String]
.
instance Foo [String] where
bar [] = []
bar (x:_) = [x]
However, I get the following compile-time error:
ghci> :l TypeClassExample.hs
[1 of 1] Compiling Main ( TypeClassExample.hs, interpreted )
TypeClassExample.hs:5:10:
Illegal instance declaration for `Foo [String]'
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use -XFlexibleInstances if you want to disable this.)
In the instance declaration for `Foo [String]'
Failed, modules loaded: none.
I'm hesitant to add this compile-time flag without understanding it.
What is its significance in this simple code?
Upvotes: 2
Views: 298
Reputation: 116139
The Haskell language definition is quite restrictive, and only allows list instances to be of the form
instance ... => Foo [a] where
where in the head a
is exactly a type variable a
, disallowing e.g. [Int]
or [String]
.
However, you can require GHC to ignore this restriction. Just add at th beginning of your file the following:
{-# LANGUAGE FlexibleInstances #-}
Many, many modern Haskell programs make use of this. Arguably, in the next Haskell definition revision, this GHC feature should be integrated.
Upvotes: 4