[mercury-users] Failing at typeclasses.

Julien Fischer juliensf at csse.unimelb.edu.au
Sun Feb 18 16:13:58 AEDT 2007

On Sat, 17 Feb 2007, Julian Fondren wrote:

> On 2/16/07, Julien Fischer <juliensf at csse.unimelb.edu.au> wrote:
>> Have a look at library/stream.  It defines several multi-parameter
>> typeclasses.
> It doesn't in the latest release, but... looking at the ROTD
> changes since 0.13.1, I think I should be using that anyway.

The stream module is not in the current release; it was added after that.

>>       :- 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
>>       ].
>> 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.
> And since the type of the seed and the type of the result are entirely
> unrelated, I can't fix this by moving forward, like I suspected :-(

It's a randome number generator; the result should surely just be a
bunch of bits (see below.

> As a horrible experiment, I changed unconstrained.m so that PRNG has
> functional dependencies ((T -> S), (T -> R)), which required duplicate
> fox_char_state fox_int_state, and then much corresponding duplication in
> the implementation.
> I think my conception of a PRNG here is simply wrong -- but with
> ROTD improvements, I might restructure things so that a PRNG takes
> a seed of random bits and then simply produces random bits, with other
> -- RNG-agnostic -- functions that turn random bits into Mercury types.

My opinion on how a random number generator typeclass should be structured
is pretty much expressed in the random typeclass in 
extras/gator/tausworthe3, e.g.

 	:- typeclass random(RNG, Seed) <= (RNG -> Seed) where

 		% (Re)seed the random number generator.
 	    pred seed(Seed, RNG,  RNG),
 	    mode seed(in,   in,   out) is det,

 		% Return the next random number.
 	    pred next(int, RNG, RNG),
 	    mode next(out, in,  out) is det,

 		% Return the maximum integer that can be
 		% returned by this random number generator.
 	    pred max(int, RNG, RNG),
 	    mode max(out, in,  out) is det

Notice that the only thing that this returns is an int.  The idea is
that for producing random elements of other types you would define
a series of predicates like:

 	:- pred random_float(float::out, RNG::in, RNG::out) is det
 		<= random(RNG, Seed).

 	:- pred random_char(char::out, RNG::in, RNG::out) is det
 		<= random(RNG, Seed).

Another example:

 	:- pred list.random_permutation(list(T)::in, list(T)::out,
 		RNG::in, RNG::out) is det <= random(RNG, Seed).


>>       :- typeclass fox_prng(T) <= prng(fox_state, fox_seed, T) where [ ].
>> #22   :- instance fox_prng(int).
>> #23   :- instance fox_prng(char).
>> 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).
> Ow, is there any use for an abbreviated typeclass like fox_prng/1, then?


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