[mercury-users] Type class usage question

Ralph Becket rafe at cs.mu.OZ.AU
Mon Apr 5 11:05:50 AEST 2004


Hi Peter,

yes, unfortunately type classes are not yet quite as easy to use as one
would like.  Once we get around to adding functional dependencies and
constructor classes this will change.  But for now, here's a sketch of
a solution.  Part of the trick is to use more than one typeclass:

:- typeclass constraint_store(T) where [
	func num_constraints(T) = int,
	... other methods that only depend on T ...
].

	% Every T in constraint_store/2 must also be in
	% constraint_store/1:
	%
:- typeclass constraint_store(T, C) <= (constraint_store(T), constraint(C))
   where [
	pred add_constraint(C::in, T::in, T::out) is det,
	... other methods that depend on both T and C ...
].

then,

:- instance constraint_store(int_constraint_store) where [
	num_constraints(T) = size(T),
	...
].

:- instance constraint_store(int_constraint_store, int_constraint) where [
	pred(add_constraint/3) is int_constraint_store_add,
	...
].

Let me know if this fixes the problem.

Cheers,
-- Ralph

peter at hawkins.emu.id.au, Saturday,  3 April 2004:
> Hi...
> 
> I'm trying to implement something using mercury but I'm hoping someone
> here can give me a better idea how to do it.
> 
> I'm trying to have code that manipulates two different kinds of
> constraints. Each kind has a corresponding constraint store that deals
> strictly with that type of constraint. The constraint store will be
> reasonably different for each kind, so simple polymorphism doesn't cut
> it, I think.
> 
> 
> :- typeclass constraint(T) where [
>     func constraint_to_thing(T) = thing
> ].
> 
> :- typeclass constraint_store(T) where [
>     % Add a constraint into the store
>     pred add_constraint(C, T, T) <= constraint(C),
>     mode add_constraint(in, in, out) is det,
> 
>     % Return the number of constraints in the store
>     func num_constraints(T) = int
> ].
> 
> Then I might have:
> 
> :- type int_constraint ---> (a == b) ; (a > b).
> :- instance constraint(int_constraint) where [
>     pred(constraint_to_thing/3) is int_constraint_to_thing
> ]. 
> 
> :- type int_constraint_store ---> c_store(
>         constraints :: list(int_constraint),
>         foo :: int,
>         bar :: string
>     ).
> :- instance constraint_store(int_constraint_store) where [
>     pred(add_constraint/3) is int_constraint_store_add,
>     num_constraints(T) = size(T)
> ].
> 
> :- pred int_constraint_store_add(int_constraint, int_constraint_store,
>             int_constraint_store).
> :- mode int_constraint_store_add(in, in, out) is det.
> int_constraint_store_add(C, S0, S) :-
>     L = S0 ^ constraints,
>     insert(C, L, L0),
>     S = (S0 ^ constraints := L).
> 
> and I might have another implementation too.
> 
> Unfortunately this doesn't compile, since the type of the first argument
> int_constraint_store_add should be (by the typeclass definition)
> some [C] C
> not:
> int_constraint
> 
> Now, what I really want is to have the constraint type as a parameter of
> the constraint store type class. Unfortunately I can't do that since
> then that constraint type has to be an argument to every predicate that
> applies to constraint store type class (including for example
> num_constraints, which obviously doesn't actually care).
> 
> How do I express what I want in Mercury?
> 
> =)
> Peter
> --------------------------------------------------------------------------
> 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
> --------------------------------------------------------------------------
--------------------------------------------------------------------------
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