[m-users.] Typeclasses

Mark Brown mark at mercurylang.org
Sat Oct 14 04:52:47 AEDT 2017


Hi Dirk,

On Sat, Oct 14, 2017 at 3:46 AM, Dirk Ziegemeyer <dirk at ziegemeyer.de> wrote:
> Hi,
>
> I’m struggling to define a typeclass for key-value-stores that provides a search_value predicate.
>
> What is wrong with to following definition?

The typeclass method you have given is more general than map.search,
so map.search can't implement it.

>
> :- import_module map.
>
> :- typeclass key_value_store(Store) where [
>     pred search_value(Store::in, K::in, V::out) is semidet
> ].
>
> :- instance key_value_store(map(K, V)) where [
>     pred(search_value/3) is map.search
> ].

The type signature for search_value in this instance is equivalent to
pred(map(K2, V2), K1, V1), where K1 and V1 are from the typeclass
declaration and K2 and V2 are from the instance declaration. They are
renamed apart because each declaration is a separate scope. So this
doesn't actually say that the types of the key and value arguments
need to match those types that are in the store.

> The compiler throws this error message:
>
> typeclass_test.m:029: In clause for type class method implementation:
> typeclass_test.m:029:   in argument 2 of predicate `map.search'/3:
> typeclass_test.m:029:   type error: variable `HeadVar__2' has type `(some [K]
> typeclass_test.m:029:   K)',
> typeclass_test.m:029:   expected type was `(some [K] K)'.

The quantifiers are a clue that these type variables are actually from
different scopes. For error messages like this one, it can be helpful
to change the variable names to be distinct for the purposes of
debugging. E.g., with the above numbering the error message is:

typeclass_test.m:016: In clause for type class method implementation:
typeclass_test.m:016:   in argument 2 of call to predicate `map.search'/3:
typeclass_test.m:016:   type error: variable `K' has type `(some [K1] K1)',
typeclass_test.m:016:   expected type was `(some [K2] K2)'.
typeclass_test.m:016: In clause for type class method implementation:
typeclass_test.m:016:   in argument 3 of call to predicate `map.search'/3:
typeclass_test.m:016:   type error: variable `V' has type `(some [V1] V1)',
typeclass_test.m:016:   expected type was `(some [V2] V2)'.

Hope that helps.

Mark


More information about the users mailing list