defaults

Duncan Coutts duncan.coutts at worc.ox.ac.uk
Mon Nov 27 19:55:02 EST 2006


On Mon, 2006-11-20 at 12:05 +0000, Malcolm Wallace wrote:
> Prompted by recent discussion on the Hat mailing list about the problems
> of type-defaulting, I have added two new proposals for this issue to the
> Haskell-prime wiki at:
> 
>     http://hackage.haskell.org/trac/haskell-prime/wiki/Defaulting
> 
> The main new proposal is a different way of specifying defaults, which
> includes the name of the class being defaulted (thus allowing
> user-defined classes to play this game), but unlike the original
> proposal, permits only one type to be specified per class.  The rules
> are therefore also simpler, whilst still (I believe) capturing the
> useful cases.

BTW, just to add another use case for allowing defaulting on any class:

One way to model OO class hierarchies (eg used in GUI libs like Gtk2Hs)
is by having a data type and a class per-object:

data Widget = ...

class WidgetClass widget where
  toWidget :: widget -> Widget --safe upcast

instance WidgetClass Widget

Then each sub-type is also an instance of the class, eg a button:

data Button = ...
class ButtonClass button where
  toButton :: button -> Button

instance WidgetClass Button
instance ButtonClass Button

etc.

So Widget is the canonical instance of WidgetClass.

Actually having this defaulting would be very useful. Suppose we want to
load a widget from a decryption at runtime (and we do, visual builders
like glade give us this). We'd have a functions like this:

xmlLoad :: WidgetClass widget => FilePath -> IO (String -> widget)

So the action loads up an xml file and gives us back a function which we
can use to lookup named widgets from the file. Of course to make this
type safe we need to do a runtime checked downcast from Widget to the
specific widget type we wish to use. For example:

getWidget <- xmlLoad "Foo.glade"
let button1 :: Button
    button1 = getWidget "button1"

It would be nice not to have to annotate that button1 :: Button. However
often it would be necessary to do so because almost all operations on
the Button type are actually generic on the ButtonClass (since there are
some sub-types of Button). So actually we'd only constrain button1 to be
an instance of ButtonClass. So we'd end up with ambiguous overloading -
just like we get with (show . read). However if we could default it to
be actually of type Button then it should all work just fine.

Duncan



More information about the Haskell-prime mailing list