[mercury-users] typeclass error
Mark Brown
mark at cs.mu.OZ.AU
Thu Jan 19 23:00:22 AEDT 2006
On 19-Jan-2006, Ian MacLarty <maclarty at cs.mu.OZ.AU> wrote:
> 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.
Without the functional dependency, they wouldn't necessarily have the same
value, let alone the same type. ;-)
Consider:
:- typeclass convertible(A, B) where [
func cast(A) = B
].
:- instance convertible(int, int) where [
(cast(N) = N)
].
:- instance convertible(int, string) where [
(cast(_) = "some number")
].
main(!IO) :-
io.write_string(cast(1), !IO),
io.nl(!IO),
io.write_int(cast(1), !IO),
io.nl(!IO).
The output would be:
some number
1
You should think of cast/1 as being an overloaded name, which is why it
appears to violate referential transparency.
Cheers,
Mark.
--------------------------------------------------------------------------
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