Kevin Meredith
Kevin Meredith

Reputation: 41909

Making TypeClass Instance for List

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

Answers (1)

chi
chi

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

Related Questions