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:
> 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
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.
More information about the Haskell-prime