[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