[m-users.] Typeclasses
Dirk Ziegemeyer
dirk at ziegemeyer.de
Sun Oct 15 06:39:30 AEDT 2017
Hi,
> Am 14.10.2017 um 16:56 schrieb Julien Fischer <jfischer at opturion.com>:
>
>
> 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.
Thank you for the tip with the wrapper types to conform to Mercury's requirement that a type in an instance declaration must be either a type with no arguments or a polymorphic type whose arguments are all type variables.
My original piece of code looked very similar to Thomas’ example and didn’t compile because I used an equivalence type in the instance declaration:
:- type store == map(int,int).
It compiles now with the wrapper type:
:- type store ---> store(map(int,int)).
Dirk.
More information about the users
mailing list