[m-users.] Typeclasses

Julien Fischer jfischer at opturion.com
Sun Oct 15 01:56:20 AEDT 2017


Hi all,

On Sat, 14 Oct 2017, Tomas By wrote:

> On 2017-10-14 14:44, Mark Brown wrote:
>>  On Sat, Oct 14, 2017 at 11:00 PM, Dirk Ziegemeyer <dirk at ziegemeyer.de>
>>  wrote:
>>>  Is it possible at all to define a typeclass key_value_store with the
>>>  method search_value and then to declare map as an instance of this
>>>  typeclass?
>>
>>  No, "map" is a constructor, not a type, so you would need a
>>  constructor class not a typeclass.
>
>
> Isn't it both?
>
> This is the closest I can get to Dirk's example:
>
>
> :- type store ---> store(map(int,int)).
>
> :- typeclass key_value_store(S) where [
>   pred search_value(S::in,int::in,int::out) is semidet
> ] .
>
> :- instance key_value_store(store) where [
>   pred(search_value/3) is my_map_search
> ] .
>
> :- pred my_map_search(store::in,int::in,int::out) is semidet.
> my_map_search(store(Map),K,V) :- map.search(Map,K,V).

I think we can do a little better than that:

First of all, if we define:

     :- typeclass key_value_store(Store, K, V) <= (Store -> K, V) where [
         pred search_value(Store::in, K::in, V::out) is semidet
     ].

then:

     :- type key(K) ---> key(K).
     :- type value(V) ---> value(V).

The instance for maps then looks like:

     :- instance key_value_store(map(K, V), key(K), value(V)) where [
         ( search_value(Map, key(Key), value(Value)) :-
             map.search(Map, Key, Value)
         )
     ].

One for red-black tree looks like:

    :- instance key_value_store(rbtree(K, V), key(K), value(V)) where [
       ( search_value(RBTree, key(Key), value(Value)) :-
           rbtree.search(RBTree, Key, Value)
       )
    ].

The wrapper types key/1 and value/1 are a bit ugly, but the restrictions
Mercury currently places upon instance heads require them.

Julien.


More information about the users mailing list