[Haskell-cafe] Has anyone looked into adding subtyping to Haskell?

Al Falloon afalloon at synopsys.com
Thu May 31 12:19:34 EDT 2007


Mark T.B. Carroll wrote:
> I don't know what the infamous "expression problem" is, nor am I
> familiar with polymorphic variants or structural subtyping, but have you
> looked at the Data.Generics.* stuff and Scrap Your Boilerplate papers?
> They may be relevant.
>   
The expression problem is "a new name for an old problem", basically 
being able to extend a data type and functions over the data type in 
seperate modules with no knowledge of each other. Here is a link to (I 
think) the original description:

http://www.daimi.au.dk/~madst/tool/papers/expression.txt

Structural subtyping is something like "duck typing" in dynamic 
languages, but checked at compile time. For records, it means that if 
you only access two labels then the function will work on any record 
that has those labels with those types, even if it may have more labels. 
For variants (or sum-types, or tagged unions, or whatever they are 
called in Haskell) it means that if your function can handle certain 
cases, then it can also handle values that range over less cases. So in 
pseudo-Haskell with imaginary subtyping:

data Vertical a = U a | D a
data Horizontal a = L a | R a
data Direction a = #Vertical a | #Horizontal a  -- borrowing ocaml 
syntax: this means that Direction shares constructors with Vertical and 
Horizontal

getData :: Direction a -> a
getData (U a) = a
getData (D a) = a
getData (L a) = a
getData (R a) = a

getLeftStick :: IO (Vertical Int)
getRightStick :: IO (Horizontal Int)

main = do { accel <- getLeftStick; print (getData accel) }

So getData doesn't care that accel is Horizontal and not Direction 
because Horizontal is a sub-type of direction. Of course, in this syntax 
since you named the subtyping relationship its more technically nominal 
subtyping (like in traditional static OO languages) not structural 
subtyping (which figures out the subtype relationship from the structure 
automatically, so if we just reused the U,D,L, and R constructors in 
Direction).

I have looked into SYB briefly. I will probably end up using it to keep 
the amount of code to a minimum, but it won't save me from having to 
define a different data type for each version of the AST if I want to 
preserve type safety.



More information about the Haskell-Cafe mailing list