[m-users.] Issue with assoc_list and other container types
Volker Wysk
post at volker-wysk.de
Sat Jan 22 06:17:36 AEDT 2022
Am Donnerstag, dem 20.01.2022 um 10:56 +1100 schrieb Peter Wang:
> On Wed, 19 Jan 2022 21:01:16 +0100 Volker Wysk <post at volker-wysk.de> wrote:
> > Hi!!
> >
> > The search predicate in the assoc_list module is like this:
> >
> > :- pred search(assoc_list(K, V)::in, K::in, V::out) is semidet.
> >
> > This leads to a problem. The mode of the output variable is "out", this
> > means that its instantiation state is "ground", after the predicate has been
> > called. I have a "call_action" predicate like this:
> >
> > :- inst assoc_list(K, V) == list(pair(K, V)).
> >
> > :- func actions =
> > ( assoc_list(string, pred(string, string))
> > :: out(assoc_list(ground, pred(in, out) is det))
> > ).
> >
> > :- pred call_action(string::in, string::in, string::out) is det.
> >
> > call_action(Action, Str, Str1) :-
> > (
> > if assoc_list.search(actions, Action, Pred)
> > then Pred(Str, Str1)
> > else throw("Bug: unknown action " ++ Action)
> > ).
> >
> > The variable "Pred" gets the instantiatedness "ground". This means that
> > "Pred(Str, Str1)" leads to a compile time error, because the
> > instantiatedness of Pred needs to be "pred(in, out) is det" for the call.
> > And such a higher-order inst is not ground.
> >
> > This means that functions/predicates can't be usefully stored in association
> > lists, because you can't call them (what else would you want to do with
> > them?).
>
> The workaround (or preferred pattern, if you like) is to define a type
> to carry the higher-order inst around:
>
> :- type action_pred
> ---> action_pred(
> pred(string::in, string::out) is det
> ).
>
> Then store values of that type in your container instead of the
> higher-order terms directly.
Okay, thanks. I'm doing it this way now.
> > :- pred assoc_list_search(
> > assoc_list(string, pred(string, string)),
> > string,
> > pred(string, string)).
> >
> > :- mode assoc_list_search(
> > in(assoc_list(Key, Val)),
> > in,
> > out(Val))
> > is semidet.
> >
> > assoc_list_search(L, K, V) :-
> > ( L = [K - V]
> > ; L = [_, K1 - V1 | Rest],
> > assoc_list_search([K1 - V1 | Rest], K, V)
> > ).
> >
> > This predicate works for call_action/3. You get the higher-order-inst of the
> > predicate, which has been found, in the search result.
> >
> > I guess, the assoc_list.search/3 and other predicates/functions should be
> > modified, and it be done this way.
> >
> > It should be the same problem with other container types (I haven't
> > checked).
>
> This works for assoc_list because the type definition is exported from
> the module. It won't work for types like types like map where the type
> is deliberately kept private.
I see. But it would work for assoc_list. Perhaps change the modes of the
predicates and functions in question?
Cheers,
Volker
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <http://lists.mercurylang.org/archives/users/attachments/20220121/3d64270e/attachment.sig>
More information about the users
mailing list