[mercury-users] Typeclass problem (bug, misunderstanding, other?)

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Aug 2 12:43:51 AEST 2000


On 01-Aug-2000, Ralph Becket <rbeck at microsoft.com> wrote:
> I have a file with a couple of typeclasses (most of
> this is chaff, you probably want to focus on the
> methods which mention node(N) as a constraint):
> 
> :- typeclass csp(T) where [
...
>     pred push_stack(conflict_fn, N, T, T) <= node(N),
>     mode push_stack(in(conflict_fn), in, in, out) is det,
>
>     pred pop_stack(list(N), T, T) <= node(N),
>     mode pop_stack(out, in, out) is det,
...
>     pred push_agenda(list(N), T, T) <= node(N),
>     mode push_agenda(in, in, out) is det,
> 
>     pred pop_agenda(conflict_fn, N, T, T) <= node(N),
>     mode pop_agenda(in(conflict_fn), out, in, out) is det
> ].
...
> :- pred solve(conflict_fn, bool, T, T) <= csp(T).
> :- mode solve(in(conflict_fn), out, in, out) is det.
> 
> solve(CFn, Solved) -->
>     ( if top_exhausted then
>         pop_stack(PoppedNodes),
>         push_agenda(PoppedNodes),
>         ( if stack_exhausted then
>             { Solved = no }
>           else
>             set_next_top_value(CFn),
>             solve(CFn, Solved)
>         )
>       else if agenda_exhausted then
>         { Solved = yes }
>       else
>         pop_agenda(CFn, NewTop),
>         push_stack(CFn, NewTop),
>         solve(CFn, Solved)
>     ).
> 
> I get the following error from the compiler (rotd 06 27,
> if memory serves):
> 
> csp.m:241: In predicate `csp:solve/4':
> csp.m:241:   type error: unsatisfied typeclass constraint(s):
> csp.m:241:   csp:node(N), csp:node(N).
> csp.m:241: In predicate `csp:solve/4':
> csp.m:241:   warning: unresolved polymorphism.
> csp.m:241:   The variables with unbound types were:
> csp.m:241:       NewTop :: N
> csp.m:241:       PoppedNodes :: (list:list(N))
> csp.m:241:   The unbound type variable(s) will be implicitly
> csp.m:241:   bound to the builtin type `void'.
> For more information, try recompiling with `-E'.
> 
> What does this mean?  I've stared and stared at the definition
> of the csp typeclass and I can't for the life of me work out
> where the error is.  If anybody can help, I'd be extremely
> grateful.

Well, if you get an error that you can't understand, the first
step should be following the compiler's suggestion: try recompiling
with `-E'.  That will give you a little bit more information:

        The body of the clause contains a call to a polymorphic predicate,
        but I can't determine which version should be called,
        because the type variables listed above didn't get bound.
        (I ought to tell you which call caused the problem, but I'm afraid
        you'll have to work it out yourself.  My apologies.)

This error happens when you do something like this:

	main -->
		io__read(X),
		io__write(X).

Here the compiler has no idea what type `X' should have.
You need to specify the type explicitly, e.g. via

	main -->
		{ qualify_type(X) },
		io__read(X),
		io__write(X).

	:- pred qualify_type(io__result(int)::unused) is det.
	qualify_type(_).   % ^^^^^^^^^^^^^^^

The compiler apologized for not telling you exactly which line of
code caused the problem, but in this case it is easy to see from
the variable names which part is the problem.  The variables with
unbound types where `PoppedNodes' and `NewTop', which each occur
only twice in your predicate.  You have two pieces of code

         pop_stack(PoppedNodes),
         push_agenda(PoppedNodes),

         pop_agenda(CFn, NewTop),
         push_stack(CFn, NewTop),

which are both similar to the `io__read(X), io__write(X)' example.

Perhaps the solution in this case may be to use existential types
for the `pop' methods, e.g.

     some [N]
     pred pop_stack(list(N), T, T) => node(N),
     mode pop_stack(out, in, out) is det,

This declaration would mean that the `pop_stack' method, rather
than its caller (solve/4), is responsible for binding the type
variable N.  That would make sense if your stacks are heterogenous
stacks (i.e. each stack can contain lists of several different types).

If your stacks are supposed to be homogeneous stacks, then probably
the right thing to do is to use a multi-parameter type class,
making `N' a type class parameter.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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