[Haskell-beginners] Equivalent of inheritance in Haskell

Paul Sargent psarge at gmail.com
Mon Dec 20 14:18:36 CET 2010


On 14 Dec 2010, at 03:10, C K Kashyap wrote:

> If I understand you right .. you'd build a 'Man' type and 'Woman' type
> by using a 'Person' type. Lets say, there is a function called getName
> that is Person -> String

In this case you can just make a new data type:

    data Person = Man {name :: String, age :: Int} | Woman {name :: String}

    marry :: Person -> Person -> String
    marry (Man m _) (Woman w)     = m ++ ", " ++ w ++ ", I know pronounce you Man and Wife"
    marry a@(Woman _) b@(Man _ _) = (name b) ++ ", " ++ (name a) ++ ", I know pronounce you Man and Wife"
    marry _       _               = error "Not in these parts!" 

The clumsy second line is just to show the function <name :: Person -> String> which accesses the name of both men and women.

The function "age" also takes a Person as it's argument, but in this case, if you ask a Woman her age things won't end well.

(..and forgive the example. I was finding it hard to come up with something that would be different for men and women without getting crude.)

This isn't the same as the classes you're describing in OO land though. Here, Man and Woman are data constructor functions which both return the type Person. There's no inheritance here, so it's *not* possible to have a Mammal data type of which Person's are a member, and so by extension Man & Woman.

Man and Woman are *not* data types themselves, so I can't write a function <giveBirth :: Woman -> Person>. I'd have to write a <giveBirth :: Person -> Person> and fail if it was passed a Man.

I personally find this type of construct very useful, but you just have to be careful to make sure you check to make sure an item can support the functions you want before calling them (e.g. 'age' above). It's not caught by the type checker at compile time, so it'll only be caught at run time and it causes an exception.




More information about the Beginners mailing list