[Haskell-beginners] joining lists sharing multiple type classes

Nick Vanderweit nick.vanderweit at gmail.com
Fri Aug 31 23:13:41 CEST 2012

It's not that your syntax is off, but rather that what you're trying to do 
doesn't really make sense in the Haskell type system. Lists are by nature 
parameterized over a single type. It is possible via existential types to have 
a list over a polymorphic type like:

exists a. (Locatable a, Animation a) => a

but this is doubtfully what you want. It suffers from the fact that, for a 
given list entry, you don't actually know what its type is, and so you can't 
do anything really useful here.

So basically: you can't have two kinds of data types in a list. What you 
probably want is a data type, like:

data Object = Star ... | Asteroid ...

That is, rather than having two types that you're trying to put in a list, 
have one type with two data constructors. Then you *can* store them together, 
and write functions that operate via pattern matching on the various 
constructors. Hope that helps.


On Friday, August 31, 2012 11:34:40 AM Christopher Howard wrote:
> Hi. I've got two data structures, Star and Asteroid (eventually I'll
> make more) that both belong to the following type classes: Locatable,
> and Animation. I wanted to do something like so in part of the code:
> code:
> --------
> let stars = ... in      -- of type [Star]
> let asteroids = ... in  -- of type [Asteroid]
> let visibleObjects = do visibleObject <- (stars ++ asteroids)
>                         ... -- prep each object for graphics system
>                             -- using funcs from both type classes
> ... -- feed visibleObjects to graphics system
> --------
> However, this does not work because the two lists are not automatically
> downgraded when joined together by (++). The compiler complains about
> "asteroids" not being of type [Star]. What is the simplest way to do
> what I am trying to do? I tried this, but I think my syntax is off:
> code:
> --------
> let visibleObjects =
>   do visibleObject <- ((stars :: [(Locatable a, Animation a) => a)
>                       ++ (asteroids :: [(Locatable a, Animation a) => a)
>                       )
> --------
> Compiler complains about "Illegal polymorphic or qualified type".

More information about the Beginners mailing list