[mercury-users] accessing typeclass dictionaries
Juergen Stuber
juergen at mpi-sb.mpg.de
Sat Nov 6 08:34:21 AEDT 1999
Fergus Henderson <fjh at cs.mu.OZ.AU> writes:
>
> On 05-Nov-1999, Juergen Stuber <juergen at mpi-sb.mpg.de> wrote:
> > On a similar note, it would also be nice to get access to
> > the dictionaries for typeclasses by some kind of low-lewel
> > Mercury. Then I could put values such as for example the N
> > for the type of integers modulo N there and access them
> > efficiently (there is already a rather inefficient way to do
> > it with existential types). This allows to use the standard
> > infix notation as the N gets passed around in the type, and
> > the typechecker makes sure I only add two numbers with the
> > same modulus.
>
> I don't really understand what you mean here.
> Perhaps you could elaborate, e.g. by showing the way to do
> it with existential types.
With existential types it is possible to encode any value
in a type that is created dynamically:
:- module et_test.
%------------------------------------------------------------
:- interface.
:- import_module io.
:- pred main( state, state).
:- mode main( di, uo ) is det.
%------------------------------------------------------------
:- implementation.
:- import_module int.
:- use_module require.
:- typeclass int_singleton(T) where [
func value(T) = int
].
:- type zero ---> zero.
:- instance int_singleton(zero) where [
func(value/1) is zero_value
].
:- type succ(N) ---> succ(N).
:- instance int_singleton(succ(N)) <= int_singleton(N) where [
func(value/1) is succ_value
].
:- func zero_value(zero) = int.
zero_value(_) = 0.
:- func succ_value(succ(N)) = int <= int_singleton(N).
succ_value(succ(N)) = value(N)+1.
:- type natural_number ---> some [N] (nat(N) => int_singleton(N)).
:- some [T] func to_natural_number(int) = T => int_singleton(T).
to_natural_number(I) = Result :-
( I=0 ->
N = 'new nat'(zero)
; I>0 ->
N1 = to_natural_number(I-1),
N = 'new nat'(succ(N1))
; % I<0,
require__error("to_natural_number: cannot convert negative integer")
),
N = nat(Result).
main -->
{ N = to_natural_number(3) },
print(value(N)),
nl.
%------------------------------------------------------------
:- end_module et_test.
If I would really use it I'd have a binary representation,
but it would still be inefficient.
> If you want to put an integer in the typeclass dictionary,
> you can use a zero-arity function method that returns an integer:
>
> typeclass foo(T) where [
> func num(T::unused) = (int::out) is det
> ].
>
> This is not quite as efficient as putting an integer in the
> typeclass dictionary, since you may end up doing an indirect
> method call rather than merely doing a load. But I find it hard
> to imagine this making a significant difference in real applications.
This is ok for me as an interface to access that value.
The problem is that I have to provide a fixed function `num'
in an instance declaration at compile time, at a time when
the number I want to return is not yet known. In some
low-level Mercury I could assemble the dictionary as I like
it when I create the first value of that type, and put a
closure that returns my value as the function for `num'.
Unfortunately my integer_modulo module where I use this is
not ready for prime time.
Jürgen
--
Jürgen Stuber <juergen at mpi-sb.mpg.de>
http://www.mpi-sb.mpg.de/~juergen/
--------------------------------------------------------------------------
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