[mercury-users] errors with typeclasses

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Nov 3 14:06:22 AEDT 2000


On 03-Nov-2000, david wallin <david at wallin.cx> wrote:
> [Fergus wrote:]
> >The problem here is that we're attempting to use the functor
> >`some_chromosome/1' is as the constructor for an existentially
> >quantified type, but in such situations the compiler requires
> >that you insert `new ' in front of the constructor name.
> >
> >So the line
> >
> >  		PopOut = list_population([some_chromosome(Chromosome) | List]).
> >
> >should be
> >
> >  		PopOut = list_population(['new 
> >some_chromosome'(Chromosome) | List]).
> 
> That worked out fine on 'list_add_chromosome/3' & 
> 'list_remove_chromosome/3', but not when I tried to apply this on 
> 'list_get_chromosome' :
> 
> %
> % list_get_chromosome
> 
> :- func list_get_chromosome(list_population, int) = C3 <= chromosome(C3).
> :- mode list_get_chromosome(in, in) = out.
> 
> list_get_chromosome(Population, Index) = Chromosome :-
> 	Population = list_population(List),
> 	get_chromosome_helper(List, Index, 'new some_chromosome'(Chromosome)).
>
> %
> % get_chromosome_helper
> 
> :- pred get_chromosome_helper(list(some_chromosome), int, some_chromosome).
> :- mode get_chromosome_helper(in, in, out).

> This resulted in the following error message :
> 
> gusga.m:088: In type class method implementation:
> gusga.m:088:   warning: unresolved polymorphism.
> gusga.m:088:   The variable with an unbound type was:
> gusga.m:088:       HeadVar__3 :: C3
> gusga.m:088:   The unbound type variable(s) will be implicitly
> gusga.m:088:   bound to the builtin type `void'.
> 
> Of course, the typeclass declaration of 'get_chromosome' looks a bit 
> different with a existential type constraint and that mode is 'out' 
> instead of 'in' as in the previous functions :
> 
> 	       some [C3] func get_chromosome(P, int) = C3 => chromosome(C3),
> 	       mode get_chromosome(in, in) = out is det
> 
> confused,

Well, if you're confused, one simple rule of thumb which will simplify
things a bit is this: the type declaration for a method implementation
should always *exactly match* the type declaration in the typeclass
with the type(s) from the `instance' declaration substituted for the
type class parameter(s).

For example, if the type class declaration is

	:- typeclass population(P) where [
	       some [C3] func get_chromosome(P, int) = C3 => chromosome(C3),
 	       mode get_chromosome(in, in) = out is det
	       ...
	].

and your instance declaration is

	:- instance population(list_population) where [ ... ].

then the type of the method implementation should be

	       some [C3] func get_chromosome(P, int) = C3 => chromosome(C3),
 	       mode get_chromosome(in, in) = out is det

with `list_population' substitute for `P', i.e.

	       some [C3] func get_chromosome(list_population, int) = C3 => chromosome(C3),
 	       mode get_chromosome(in, in) = out is det

You've used a more general type declaration for list_get_chromosome,

	       func list_get_chromosome(list_population, int) = C3 <= chromosome(C3),
 	       mode list_get_chromosome(in, in) = out is det

and the compiler will allow that, but in this case it won't do what you want.
This type is more general since it promises to work for all chromosome types C3
rather than just for some chromosome type C3.
The warning message that you get (which in fact should probably be an _error_
rather than a warning) is due to this difference in signatures .

Now, lets have a look at the code for list_get_chromosome:

> list_get_chromosome(Population, Index) = Chromosome :-
> 	Population = list_population(List),
> 	get_chromosome_helper(List, Index, 'new some_chromosome'(Chromosome)).

The `new' prefix must only be used when you are constructing an object,
not when deconstructing it.  Here `Chromosome' has mode `out', not `in', 
so what you are trying to do is to deconstruct the object.  Hence you
should not use `new ' here.

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