[Haskell-beginners] How do I define data types with arbitrary content?

Daniel Fischer daniel.is.fischer at googlemail.com
Sun Sep 11 15:27:01 CEST 2011

On Sunday 11 September 2011, 14:21:10, Alexander Raasch wrote:
> Hi,
> just for the sake of deepening my understanding of Haskell types, I'm
> looking for a way to define a data type, like list or tree, that takes
> arbitrary values as its content.
> In Java, I would write
> class Tree { Object node; Tree left; Tree right; }
> and that allows me to put Integers, Strings, or anything into the tree,
> since they all inherit from Object. How would I go about defining such a
> type in Haskell?

In general, you don't. Such a structure would be pretty useless, since one 
couldn't call any interesting functions on the values it contains.
If you're absolutely determined to do it, there are ways, but really, 
please don't.
If you don't want the full generality of being able to put *anything* in 
your tree (and you probably don't), there are sufficiently nice ways of 
doing something like that.

> I'm reading www.learnyouahasell.com and all of the examples use only a
> single type parameter as in
> data Tree a = Nil | Node a (Tree a) (Tree a)
> so you can't mix Integers and Strings for example.

Yes, there are different operations for Strings and Integers, so that 
prevents calling e.g. ("Hello" ^ "world") or (tail 5).
Hence it is a good thing.

Generally, you have a (small) set of types you're interested in, then you 
can define a type

data Wrapper
    = I Integer
    | S String
    | B Bool

and use that to wrap your values; or you're interested in types supporting 
some specific operations, then you can use an existential wrapper:

{-# LANGUAGE ExistentialQuantification #-}

data Foo = forall a. (Class1 a, Class2 a) => Foo a

Then you use (Tree Foo) and wrap your values in a Foo to put them in the 
tree. You can then use the methods of Class1 and Class2 on the values
(more conveniently if you define instances of Class1 and Class2 for Foo

instance Class1 Foo where
    method (Foo x) = method x

that's somewhat similar to Java interfaces), but only those.

More information about the Beginners mailing list