Algebraic types and subclassing
Arjan van IJzendoorn
arjanij@cs.kun.nl
Thu, 12 Mar 1998 10:34:08 +0100
Hi Nick,
>The difference is that:
>
>Add :: Int Int -> Int
>Add = (+)
>
>Doesn't work, although I think it ought to.
Why not write "Add :: (Int -> Int -> Int); Add = (+)" ?
Then the type doesn't look so nice, but the definition does.
>>>- Language level support for ADTs. Data hiding is pretty tricky without
>>>this. And you *can't* hide types without this.
>>
>>It is possible to hide types using the module structure of Clean (exporting
>the type >constructor, but not its definition.
>
>The idea is to not allow the programmer to construct types himself. RGB
>1092348 1024980918 24096834 is obviously invalid. If you had an ADT, your
>makeRGB function could throw exceptions with such parameters. The idea is to
>prevent these sort of things from being even possible.
>(Note that this example could be satisfied by my proposed class
>"assertions:"
Again, this can be done by using Clean's module system:
--------------
definition module RGB
:: RGB // Note: the implementation is not revealed
makeRGB :: Int Int Int -> RGB // The "constructor"
-------------
implementation module RGB
import StdEnv
:: RGB = { red :: Int, green :: Int, blue :: Int }
makeRGB :: Int Int Int -> RGB
makeRGB red green blue
| all (between 0 255) [red, green, blue]
= { red = red, green = green, blue = blue }
| otherwise
= abort "makeRGB (RGB.icl): illegal arguments"
between :: Int Int Int -> Bool
between lower upper value
= value >= lower && value <= upper
------------------
Now, users of the module RGB can only construct RGB values using
the constructor.
Bye,
Arjan