[mercury-users] Typeclass problem (bug, misunderstanding, oth er?)
Ralph Becket
rbeck at microsoft.com
Thu Aug 10 19:15:05 AEST 2000
> From: Fergus Henderson [mailto:fjh at cs.mu.OZ.AU]
>
> On 09-Aug-2000, Ralph Becket <rbeck at microsoft.com> wrote:
> > Sorry to keep harping on about this one, but I am
> > just totally bemused. Can you go through the type
> > inference on this one line by line and point out
> > where the error is?
> > [...]
> >
> > :- typeclass tc(T1, T2) where [
> > func e(T1) = T1,
> > func f(T1) = T2,
> > func g(T1, T2) = T2
> > ].
>
> The `e' method here is already problematic. The compiler really ought
> to issue an error or at least a warning at this point, since there is
> no way that e/1 can be called without an ambiguous type error.
> (Thank you for continuing to harp on this point, since by doing so you
> have identified an area in which we can easily improve the compiler's
> diagnostics.)
>
> The type for `e' is
>
> :- func e(T1) = T1 <= tc(T1, T2).
>
> The problem is that none of the arguments to or result of this
> function contain the type `T2', so there is no way that the `T2'
> type parameter can ever be constrained.
Kum by yah! We've got it sorted! A comment to this effect
really should go into the documentation, prefereably with a
big neon sign nearby. It is quite subtle.
> The solution is to make that function a member of a different
> single-parameter type class, and have the multi-paramater type
> class inherit from the single parameter type class:
>
> :- typeclass base(T1) where [
> func e(T1) = T1
> ].
> :- typeclass tc(T1, T2) <= base(T1) where [
> func f(T1) = T2,
> func g(T1, T2) = T2
> ].
Got it. This suggests a new bit of syntax, since I suspect cases
like this are going to be quite common. It would be quite handy
to be able to say
:- typeclass foo(T1, T2, T3) => bar(T1, T2), baz(T2, T3), quux(T3).
where foo/3 is just an abbreviation for the RHS.
> Consider the following similar function:
>
> :- func bar2(X1) = pair(X2,X3) <= (tc(X1, X2), tc(X1, X3)).
>
> bar2(A) = g(E, f(A)) - g(E, f(A)) :-
> E = e(A).
>
> Here it is not clear whether the type T2 in the type class constraint
> for e/1 should be bound to X2 or to X3.
>
> The compiler can't infer that T2 should be bound to X2 simply
> because (X1, X2) is known to be an instance of the class tc/2,
> since there may be other instances (e.g. (X1, X3)) that also match but
> which have different semantics.
I think I might try to summarise this discussion and add it to the
FAQ. It's been most illuminating.
Cheers,
Ralph
--------------------------------------------------------------------------
mercury-users mailing list
post: mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the users
mailing list