[m-users.] Ambiguous overloading error, with_type suggested

Sean Charles (emacstheviking) objitsu at gmail.com
Sun Jun 13 18:43:17 AEST 2021

> list.filter exists both as a predicate and as a function. The predicate form
> takes a predicate as first arg, while the function form takes a function.
> The first error is mixing up these two. This unification does not bind Tokens
> to a list of tokens; it binds it to a closure.
> Zoltan.

Hi Zoltan, Than you for your reply to my problem, I have taken the time to try to learn and understand, I apologise for the length of my reply but I have tried to dig deep and get to the bottom of it so I may better understand in the future, my mileage did indeed vary...

Listing the filter calls:

:- func filter(pred(X)::in(pred(in) is semidet), list(X)::in) = (list(X)::out) is det.
:- pred filter(pred(X)::in(pred(in) is semidet), list(X)::in, list(X)::out) is det.
:- pred filter(pred(X)::in(pred(in) is semidet), list(X)::in, list(X)::out, list(X)::out) is det.

Your response says that the function form takes a function as the first arg but they all take a closure as the first argument, at least from looking  at the source code for 20.06.01.

The predicate forms unify a list of those elements that pass the test, or a list of both passes and fails. I checked section 2.15.5 of the reference manual, Lambda expressions, and it shows a ‘closure’ as having one of these forms:

pred(Arg1::Mode1, Arg2::Mode2, ...) is Det :- Goal
pred(Arg1::Mode1, Arg2::Mode2, ..., DCGMode0, DCGMode1) is Det --> DCGGoal func(Arg1::Mode1, Arg2::Mode2, ...) = (Result::Mode) is Det :- Goal func(Arg1, Arg2, ...) = (Result) is Det :- Goal
func(Arg1, Arg2, ...) = Result :- Goal

I see no version of filter that takes a ‘func’ as the first argument. Returning to my broken code,

Tokens = list.filter(
    (pred(T::in) is semidet :- Ty = tok_type(T), not (Ty = c1 ; Ty = cn)),

simplifying this to:

    Pr = (pred(T::in) is semidet :- Ty = tok_type(T), not (Ty = c1 ; Ty = cn)),
    Tk = tokens(Lx),
    Tokens = list.filter(Pr, Tk),

If I understand your response correctly, you are saying that Tokens is in fact bound to a closure presumably because I have failed to fully satisfy a func/pred form and ended up with, in Haskell terminology, a partial application?

Changing my code to read:

	list.filter(Pr. Tk, Tokens)

compiles as the first predicate form was satisfied, changing it to this:

    list.filter(Pr, Tk, Tokens, Comments),

also compiles as the second predicate form is used (this might be useful in the future actually :) and this code:

    Tokens = list.filter(Pr, Tk)

obviously still fails to compile and I still fail to understand. At least I can know the predicate form is good for now. I will ponder the hidden deeper meaning of your original reply some other time. As the message instructed, I did get it to compile like this:

    Tokens `with_type` list(token) = list.filter(Pr, Tk),

I read a lot of call site uses in the mercury code base to get a feel for it, but alas I still fail to fully understand the original issue.   :|

Thanks again Zoltan.

More information about the users mailing list