[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.
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