Difference between revisions of "List instance"

From HaskellWiki
Jump to navigation Jump to search
(Category:FAQ)
(Haskell code markup)
Line 5: Line 5:
   
   
If I have a type class for conversion to a type X:
+
If I have a type class for conversion to a type <hask>X</hask>:
   
 
<haskell>
 
<haskell>
Line 20: Line 20:
 
</haskell>
 
</haskell>
 
 
but not for Strings, given that they are a synonym for [Char]. Hence:
+
but not for Strings, given that they are a synonym for <hask>[Char]</hask>. Hence:
   
 
<haskell>
 
<haskell>
Line 45: Line 45:
 
with calls to this constructor.
 
with calls to this constructor.
   
I'm aware of the approach taken by class Show in the prelude, which
+
I'm aware of the approach taken by class <hask>Show</hask> in the prelude, which
 
adds a extra method to the class:
 
adds a extra method to the class:
 
 

Revision as of 22:03, 26 May 2007

Question

How to make a list type an instance of some type class in Haskell 98? Haskell 98 does not support instances on particular composed types like String.


If I have a type class for conversion to a type X:

 
    class C a where
        toX   :: a -> X

I can define instances for

    instance C Int where toX  = ...
    instance C Double where toX  = ...
    instance C Tuple where toX  = ...

but not for Strings, given that they are a synonym for [Char]. Hence:

    instance C String where toX  = ...

results in:

   Illegal instance declaration for `C String'
       (The instance type must be of form (T a b c)
        where T is not a synonym, and a,b,c are distinct type variables)
   In the instance declaration for `C String'

Is there some type class cleverness that can make this work in haskell 98? I can create a new wrapper type for strings:

    newtype StringWrap = StringWrap String

and write an instance for that, but then I'll have to litter my code with calls to this constructor.

I'm aware of the approach taken by class Show in the prelude, which adds a extra method to the class:

    class C a where
        toX     :: a -> X
        listToX :: [a] -> X

but I believe this says that whenever we can convert a to an X we can also convert [a] to an X, whereas I only want [Char] to be acceptable.

Answer

The trick in the Prelude is that listToX has a default implementation.

If this is not possible in your application then introduce a new class like

    class Element a where
        listToX :: [a] -> X

and define instances like

    instance Element Char where
        listToX = ...

    instance Element a => C [a] where
        toX = listToX

.

Source

http://www.haskell.org/pipermail/haskell-cafe/2007-May/025742.html