[mercury-users] Failing at typeclasses.
Julien Fischer
juliensf at csse.unimelb.edu.au
Sat Feb 17 13:54:19 AEDT 2007
On Fri, 16 Feb 2007, Julian Fondren wrote:
> I get the attached errors from compiling the attached module,
> which itself is meant to yield these errors that I get from
> a much longer random.m that I work on, with similar typeclass
> use (or attempted use).
>
> Can someone please just show me a correct typeclass use with
> this many variables?
>
> :- typeclass prng(T, S, R) <= (state(T), seed(S), return(R)) where [
> pred seed(S::in, T::uo) is det,
> pred random(R::out, T::di, T::uo) is det
> ].
> :- typeclass fox_prng(T) <= prng(fox_state, fox_seed, T) where [ ].
> :- instance fox_prng(int).
> :- instance fox_prng(char).
Have a look at library/stream. It defines several multi-parameter
typeclasses.
You should also have a look at extras/gator/tausworthe3 which
includes a typeclass for a random number generators.
> Sorry if this request is a bit lame, but I'm at the point
> where I think I'd progress more by throwing the typeclasses
> away entirely and using module-based polymorphism, or by
> learning about existential types. Insofar as I understand
> these errors, they don't seem fixable.
They are perfectly fixable:
:- module unconstrained.
:- interface.
:- import_module int, char, pair, string.
:- typeclass seed(T) where [ ].
:- typeclass state(T) where [ ].
:- typeclass return(T) where [ ].
:- typeclass prng(T, S, R) <= (state(T), seed(S), return(R)) where [
#10 pred seed(S::in, T::uo) is det,
#11 pred random(R::out, T::di, T::uo) is det
].
unconstrained.m:010: In declaration for predicate `unconstrained.seed'/2:
unconstrained.m:010: error in type class constraints: type variable R occurs
unconstrained.m:010: in the constraints, but is not determined by the
unconstrained.m:010: predicate's argument types.
unconstrained.m:011: In declaration for predicate `unconstrained.random'/3:
unconstrained.m:011: error in type class constraints: type variable S occurs
unconstrained.m:011: in the constraints, but is not determined by the
unconstrained.m:011: predicate's argument types.
This error is cause by the fact that the two method declarations do
not follow the rules for the type signatures of methods in section
10.1 of the reference manual:
For each method, all parameters of the typeclass must be determined by
the type variables appearing in the type signature of the method. A
variable is determined by a type signature if it appears in the type
signature, but if functional dependencies are present then it may also
be determined from the other variables (see Functional dependencies).
There are no functional dependencies in the above typeclass declaration
and method seed does not refer to type variable R in it's signature;
likewise method random does not refer to type variable S in it's signature.
:- instance seed(fox_seed).
:- instance state(fox_state).
:- typeclass fox_prng(T) <= prng(fox_state, fox_seed, T) where [ ].
#22 :- instance fox_prng(int).
#23 :- instance fox_prng(char).
unconstrained.m:022: In instance declaration for `unconstrained.fox_prng(int)'
unconstrained.m:022: superclass constraints not satisfied:
unconstrained.m:022: `unconstrained.prng((pair.pair(string, int)), string,
unconstrained.m:022: int)'.
unconstrained.m:023: In instance declaration for
unconstrained.m:023: `unconstrained.fox_prng(character)' superclass
unconstrained.m:023: constraints not satisfied:
unconstrained.m:023: `unconstrained.prng((pair.pair(string, int)), string,
unconstrained.m:023: character)'.
The typeclass declaration says that if T is an instance of fox_prng/1 then
prng(fox_state, fox_seed, T) must be an instance of prng/3. There are no
such instances in your program., e.g. the compiler is complaining that the
following are not defined:
:- instance prng(fox_state, fox_seed, int).
:- instance prng(fox_state, fox_seed, char).
(In the error message it has rather inconveniently expanded all the
equivalence types which means that this may not be as obvious as it should.)
:- implementation.
:- instance seed(fox_seed) where [ ].
:- instance state(fox_state) where [ ].
#30 :- instance fox_prng(int) where [
pred(seed/2) is fox_seed,
(random(R, !RNG) :- fox_rand(R0, !RNG), char.to_int(R0, R))
].
unconstrained.m:030: In instance declaration for `unconstrained.fox_prng(int)'
unconstrained.m:030: superclass constraints not satisfied:
unconstrained.m:030: `unconstrained.prng((pair.pair(string, int)), string,
unconstrained.m:030: int)'.
unconstrained.m:030: In instance declaration for `unconstrained.fox_prng'/1:
unconstrained.m:030: incorrect method name(s): predicate
unconstrained.m:030: `unconstrained.seed'/2 predicate
unconstrained.m:030: `unconstrained.random'/3.
The problem here is that the typeclass fox_prng/1 has no methods named
seed/2 or random/3. They are methods of the superclass prng/3.
Note that in Mercury you cannot define the methods of the superclass
in an instance declaration for a sub-class and expect it to act as
an instance definition for the superclass as well. You need a separate
instance definition for the superclass.
:- instance fox_prng(char) where [
pred(seed/2) is fox_seed,
pred(random/3) is fox_rand
].
unconstrained.m:035: In instance declaration for
unconstrained.m:035: `unconstrained.fox_prng(character)' superclass
unconstrained.m:035: constraints not satisfied:
unconstrained.m:035: `unconstrained.prng((pair.pair(string, int)), string,
unconstrained.m:035: character)'.
unconstrained.m:035: In instance declaration for `unconstrained.fox_prng'/1:
unconstrained.m:035: incorrect method name(s): predicate
unconstrained.m:035: `unconstrained.seed'/2 predicate
unconstrained.m:035: `unconstrained.random'/3.
Same problem here.
Julien.
--------------------------------------------------------------------------
mercury-users mailing list
Post messages to: mercury-users at csse.unimelb.edu.au
Administrative Queries: owner-mercury-users at csse.unimelb.edu.au
Subscriptions: mercury-users-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the users
mailing list