Extensible Algebraic Data Types
Ashley Yakeley
ashley@semantic.org
Fri, 2 Mar 2001 17:36:15 -0800
I think it would be useful to extend Haskell so that one could create
algebraic data types in one module that could be union-extended in
another. Something like this:
data Thing = CharThing Char | IntThing Int | _
...later...
data Thing |= StringThing String
This would be useful for two reasons:
1. You could do something akin to dynamic typing without unreasonably
stressing the ideas behind the Haskell type system:
data BaseExtension = _
data Base = MkBase (Char,Int,BaseExtension)
...later...
data Derived = MkDerived (Char,Int,Int,Int)
data BaseExtension |= MkDerivedExtension (Int,Int)
upcast :: Derived -> Base
upcast (MkDerived (a,b,c,d)) = MkBase (a,b,MkDerivedExtension(c,d))
downcast :: Base -> Maybe Derived
downcast MkBase (a,b,MkDerivedExtension(c,d)) = Just (MkDerived (a,b,c,d))
downcast MkBase (a,b,_) = Nothing
2. You'd have a way of autogenerating values similar to LISP's gensym:
data Token = _ deriving Eq
...later...
data Token |= ThisToken
data Token |= ThatToken
data Token |= BunchOfTokens Int
Of course this extension to Haskell begs another, virtual or generic
functions. I'm not sure how to do this properly while maintaining the
principle that an expression has the same value regardless of other
modules loaded.
data Thing = CharThing Char | IntThing Int | _
f1 :: Thing -> Int
f1 (CharThing c) = ord c
f1 (IntThing i) = i
-- somehow allow cases to be inserted later here
f1 _ = 0
-- multiple dispatch
f2 :: Thing -> Thing -> Int
f2 (IntThing i) (IntThing j) = i + j
-- might want cases inserted here,
-- provided they don't cause trouble
f2 (IntThing i) _ = i
-- or here
f2 _ (IntThing i) = i + 1
-- or here
f2 _ _ = 0
Are these ideas something worth thinking about? Or would such extensions
compromise important principles behind Haskell?
--
Ashley Yakeley, Seattle WA