[mercury-users] typeclass error
Ian MacLarty
maclarty at cs.mu.OZ.AU
Thu Jan 19 19:13:02 AEDT 2006
On 19 Jan 2006, at 05:39, Mark Brown wrote:
> On 18-Jan-2006, Ian MacLarty <maclarty at cs.mu.OZ.AU> wrote:
>> Hello,
>>
>> What's wrong with the following program?
>>
>> :- module tc.
>>
>> :- interface.
>>
>> :- import_module io.
>>
>> :- pred main(io::di, io::uo) is det.
>>
>> :- implementation.
>>
>> :- import_module list, int.
>>
>> main(!IO) :-
>> nl(!IO).
>>
>> :- typeclass tc1(A, C) where [
>> func a_to_c(A) = C
>> ].
>>
>> :- typeclass tc2(B, C) where [
>> func b_to_c(B) = C
>> ].
>>
>> :- func f(A, B) = C <= (tc1(A, C), tc2(B, C)).
>>
>> f(A, B) =
>> ( if a_to_c(A) = b_to_c(B) then
>> a_to_c(A)
>> else
>> b_to_c(B)
>> ).
>
> First, here's the clause with some explicit type annotations:
>
> f(A, B):C0 =
> ( if a_to_c(A):C1 = b_to_c(B):C2 then
> a_to_c(A):C3
> else
> b_to_c(A):C4
> ):C5.
>
> Because of the result unification, we know that C0 = C5. Because of
> the
> semantics of if-then-else expressions, we know that C3 = C5 and C4 =
> C5.
> Because of the unification in the condition, we know that C1 = C2. So
> at
> this stage there are two equivalence classes: {C0,C3,C4,C5} and
> {C1,C2}.
> There is nothing in the clause which implies that these two equivalence
> classes are the same.
>
> The first equivalence class is the type of the function result, so it
> is
> bound to the universally quantified C from the func declaration. Hence
> the method calls in the "then" and "else" branches will call methods in
> those dictionaries that are passed in as hidden arguments to f (that
> is,
> the dictionaries that correspond to the two constraints on the func
> declaration).
>
> The second equivalence class remains unbound. Hence there are no
> assumed
> constraints (e.g., constraints on the func declaration) that can
> satisfy
> the constraints on the method calls in the condition; this explains the
> first part of the error message. The warning you get is because
> unbound
> type variables are generally never what the programmer intends.
>
That all makes perfect sense. I was under the illusion that the
compiler would know that C1 and C3 are of the same type, because they
have the same value, but I guess type inference doesn't know anything
about the values.
>>
>> I get the following error when I try to compile it:
>>
>> tc.m:024: In function `tc.f/2':
>> tc.m:024: type error: unsatisfied typeclass constraints:
>> tc.m:024: `tc.tc1(A, C)'
>> tc.m:024: `tc.tc2(B, C)'
>> tc.m:024: In function `tc.f/2':
>> tc.m:024: warning: unresolved polymorphism.
>> tc.m:024: The variable with an unbound type was:
>> tc.m:024: V_6: C
>> tc.m:024: The unbound type variable(s) will be implicitly
>> tc.m:024: bound to the builtin type `void'.
>
> The error message would be better if the location of the place where
> the
> constraint arose in the clause was reported, rather than the location
> of
> the func declaration. But the compiler doesn't currently keep enough
> information to be able to do that, unfortunately.
>
> Here are two ways that you can get the code to compile:
>
> a) Rewrite the clause so that there are unifications that imply that
> C1 and
> C2 are the same as C. For example:
>
> f(A, B) = C :-
> C0 = a_to_c(A),
> ( if C0 = b_to_c(B) then
> C = C0
> else
> C = b_to_c(B)
> ).
>
> b) Add functional dependencies so that the compiler can "improve" the
> types
> C1 and C2 to be equal to C. For example:
>
> :- typeclass tc1(A, C) <= (A -> C) where [ ... ].
>
> or
>
> :- typeclass tc2(B, C) <= (B -> C) where [ ... ].
>
Actually the code I gave was a simplification of another problem I was
trying to solve. I've opted to use higher order code instead of
typeclasses which gets around the type error.
Thanks for your help,
Ian.
--------------------------------------------------------------------------
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