It seems that Frege's ideas about type-classes differ significantly from Haskell. In particular:
The syntax appears to be different, for no obvious reason.
Function types cannot have class instances. (Seems a rather odd rule...)
The language spec says something about implementing superclasses in a subclass instance declaration. (But not if you have diamond inheritance... it won't be an error, but it's not guaranteed to work somehow?)
Frege is less fussy about what an instance looks like. (Type aliases are allowed, type variables are not required to be distinct, etc.)
Methods can be declared as
native
, though it is not completely clear what the meaning of this is.It appears that you can write
type.method
to access a method. Again, no indication as to what this means or why it's useful.Subclass declarations can provide default implementations for superclass methods. (?)
In short, it would be useful if somebody who knows about this stuff could write an explanation of how this stuff works. It's listed in the language spec, but the descriptions are a little bit terse.
(Regarding the syntax: I think Haskell's instance syntax is more logical. "If X is an instance of Y and Z, then it is also an instance of Q in the following way..." Haskell's class syntax has always seemed a bit strange to me. If X implements Eq
, that does not imply that it implements Ord
, it implies that it could implement Ord
if it wants to. I'm not sure what a better symbol would be though...)
Per Ingo's answer:
- I'm assuming that providing a default implementation for a superclass method only works if you declare your instances "all at once"?
For example, suppose Foo
is a superclass of Bar
. Suppose each class has three methods (foo1
, foo2
, foo3
, bar1
, bar2
, bar3
), and Bar
provides a default implementation for foo1
. That should mean that
instance Bar FB where foo2 = ... foo3 = ... bar1 = ... bar2 = ... bar3 = ...
should work. But would this work:
instance Foo FB where foo2 = ... foo3 = ... instance Bar FB where bar1 = ... bar2 = ... bar3 = ...
- So if I declare a method as
native
in a class declaration, that just sets the default implementation for that method?
So if I do something like
class Foobar f where foo :: f -> Int native foo bar :: f -> String native bar
then that just means that if I write an empty instance declaration for some Java native class, then foo
maps to object.foo()
in Java?
In particular, if a class method is declared as native
, I can still provide some other implementation for it if I choose to?
- Every type [constructor] is a namespace. I get how that would be helpful for the infamous named fields problem. I'm not sure why you'd want to declare other things in the scope of this namespace...