Extensible records in Haskell

John Meacham john@repetae.net
Thu, 7 Nov 2002 13:08:18 -0800

Are you sure extensible records are needed, I used to really want them
until I developed some idioms which seem to replace most needs for them.

(1) Haskell Records
just plain old haskell records can be used in an extensible fashion
quite easily, just provide an alternate to the constructor which fills
uninitialized fields with sane values. for example

data Employee = Emp {empName :: String, empNumber :: Int}

now, rather than creating them like

john = Emp {empName = "John Meacham", empNumber = 7} 

provide a default value

employee = Emp {empName = "", empNumber = 0}  -- I tend to use the type
                                              -- name uncapitalized

and use that instead of the constructor everywhere like so

john = employee {empName = "John Meacham", empNumber = 7} 

now, to extend it, just add a new field to both the type and your

data Employee = Emp {empName :: String, 
	empNumber :: Int, empIsDisgruntled :: Bool}

employee = Emp {empName = "", empNumber = 0, empIsDisgruntled = False} 

now notice all your old code still works perfectly, the new fields
just take on their default value

john = employee {empName = "John Meacham", empNumber = 7} 

(2) Function Dispatch

often times when you want extensible data types, you really dont even
need data types at all, manual deforestation could lead to a nicely
extensible framework. take the following

type Width = Int
data Doc = DocString String | DocVert [Doc] | DocHoriz [Doc] 
renderDoc :: Doc -> Width -> String
renderDoc = {- complicated code -}

now, you want to add the possibility of an image to your document but
that would require modiying everywhere that Doc is deconstructed to
account for that possibility. well, why not get rid of the Doc type

type Doc = Width -> String

a document is now considered _anything_ that can render itself, no need
for extensible types as any function of the appropriate type can be used
as a document plus your code is easier to maintain. 

even if your entire structure cannot be boiled down to a function type,
just parts of your structure can be. anywhere you want an extensible
disjunction is a canidate.

(3) Strafunski http://www.cs.vu.nl/Strafunski/

generic programming also makes this easy, (although it does require some
commonly implemented extensions). since strafunski provides all your
term traversal functionality, which is exactly where current datatypes
fall down when you try to extend them, you can usually modify your
data types all you want and use your 'generic' functions implemented
with strafunski on them. see the web page for much better examples than
I can come up with.

sorry if this post is way off base, but perhaps someone will find it
useful. (this should go in the Wiki. poor Wiki.)

On Wed, Nov 06, 2002 at 09:37:45AM +0100, Nicolas Oury wrote:
> I need something that can allow to use records without declaring their 
> type first and that can be extended by creating a new records with the 
> same contents plus one or less one.
John Meacham - California Institute of Technology, Alum. - john@foo.net