
"Neil Mitchell"
To make things concrete, the example I'm really thinking of is a "send an email" function, which would take a subject, a body, a list of recipients, optional lists of cc and bcc recipients, an optional mailserver (default localhost), an optional port (default 25), and possibly optional authentication details.
Records are your friend.
data Email = Email {subject :: String, body :: String, to :: [Address], cc = [Address], bcc = [Address], mailserver :: String, port :: Int}
defaultEmail = Email{subject = "No subject", body = "", to = [], cc = [], bcc = [], mailserver = "localhost", port = 25}
The user can then go:
sendEmail defaultEmail{subject="Subject here", body = "body here", to = ["haskell-cafe"], mailserver = "server.haskell.org"}
Now things which are't specified (port) keep their default value.
If you do this for more than one function (and consequently more than one datatype) there's a case for a class -- something like: class Defaultable t where defaults:: t instance Defaultable Email where defaults = Email{subject = "No subject", body = "", to = [], cc = [], bcc = [], mailserver = "localhost", port = 25} which would save having a defaultFoo for every Foo (at the possible expense of occasional explicit types). -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk