[m-users.] higher order issue: `ground` seen but expecting higher-order pred

Volker Wysk post at volker-wysk.de
Wed Oct 5 13:01:01 AEDT 2022


Am Dienstag, dem 04.10.2022 um 21:44 +0100 schrieb Sean Charles
(emacstheviking):
> I am fleshing out a VERY loose forth type system, I have the following
> definitions to allow me to set up a map of word names and there handlers:
> 
> :- type lstr == list(string).
> 
> :- type word_handler == (pred(fstate, fstate, io, io, lstr, lstr)).
> :- inst word_handler == (pred(in, out, di, uo, in, out)is det).
> 
> :- type word_map == map(string, word_handler).
> :- type stack_entry == stack(int).
> 
>     %
>     % FBNF operating state
>     %
> :- type fstate
>     --->    fstate(
>                 fs_dict  :: word_map,
>                 fs_stack :: stack_entry,
>                 fs_error :: maybe(string)
>             ).
> 
> then I initialise the default word list like this:
> 
> initial_dictionary = Map :-
>     some [!Words] (
>         !:Words = map.init,
>         map.set(":",     define_word, !Words),
>         map.set("words", list_words,  !Words),
>         Map = !.Words
>    ).
> 
> Here are the implementations of the above two default words:
> 
> :- pred define_word(fstate::in, fstate::out, io::di, io::uo,
>     lstr::in, lstr::out) is det.
> 
> define_word(!State, !IO) -->
>     {
>         io.format("DEFINE WORD\n", [], !IO)
>     }.
> 
> 
> :- pred list_words(fstate::in, fstate::out, io::di, io::uo,
>     lstr::in, lstr::out) is det.
> 
> list_words(!State, !IO) -->
>     {
>         io.format("WORDS\n", [], !IO)
>     }.
> 
> 
> and eventually when I try to call it, I get the error on the line shown ,
> here I look up the word in the map into Entry, and try to call it:
> 
> :- pred execute(string::in, fstate::in, fstate::out, io::di, io::uo,
>     lstr::in, lstr::out) is det.
> 
> execute(Word, !State, !IO) -->
>     { Words = fs_dict(!.State) },
>     ( if { map.search(Words, Word, Entry) } then
> 
> (191)        Entry(!State, !IO)        <====== compiler hate this line!
> 
>     else
>         { set_error(
>             string.format("word not found: %s\n",
>             [s(Word)]), !State) }
>     ).
> 
> 
> fbnf.m:191: In clause for `execute(in, in, out, di, uo, in, out)':
> fbnf.m:191:   in argument 1 (i.e. the predicate term) of higher-order
> predicate
> fbnf.m:191:   call:
> fbnf.m:191:   mode error: variable `Entry' has instantiatedness `ground',
> fbnf.m:191:   expecting higher-order pred inst of arity 6.
> 
> 
> 
> I am not sure the DCG style will remain but it's pure proof of concept /
> exploratory at the moment. I used getopt.m as inspiration but obviously
> talent and brains are needed as well... what have I not told the compiler
> that it needs to know ?

It's that prevalent higher-order-insts in the standard libraries issue. This
is the declaration of map.search/3:

:- pred search(map(K, V)::in, K::in, V::out) is semidet.

It should be:

:- pred search(map(K(I), V(J))::in, K(I)::in, V(J)::out) is semidet.

The way it is, the higher order inst of the word_handler map gets lost when
calling map.search/3. "Entry" becomes just ground, what can't be called as a
predicate.

You need to encapsulate word_handler, like this:

:- type word_handler 
    ---> word_handler(
            word_handler
            :: pred(fstate, fstate, io, io, lstr, lstr)).

Then you can call the encapsulated predicate like this:

    (word_handler(Entry))(!State, !IO)


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/20221005/2b66c639/attachment.sig>


More information about the users mailing list