(The excerpt below is from this test suite, which is half of the two-file program found here.)
I've defined an auxiliary predicate in two ways: once at the top level (called helper), and once as a lambda (called Helper). In the last three lines of the code below, I use that auxiliary predicate. If I use helper it works, but if I use Helper I get an error (below).
I suspect the problem might be that I am able to specify a type signature as well as a mode signature for the type-level predicate, but only a mode signature for the lambda. (If that's the problem, I don't know what to do about it.)
Here's the relevant code:
:- pred helper( query, int ).
:- mode helper( in, out ) is nondet.
helper( Q, F ) :-
inQuery( fiveNumberSpace, Q, F ).
testQAnd = Res :-
QQF = qqFind( qFind( list.filter( <(3) ) ) )
, QQC = qqCond( qCond( func( Int )
= (if Int > 4 then no else yes) ) )
, Helper = ( pred( Q :: in, F :: out ) is nondet :-
inQuery( fiveNumberSpace, Q, F ) )
% TODO Why can't I use Helper instead of helper for these?
, solutions( helper( qqAnd( [QQF ] ) ) , F1 )
, solutions( helper( qqAnd( [QQF, QQC] ) ) , F2 )
, solutions( helper( qqAnd( [ QQC] ) ) , F3 )
Here's the error I get from using Helper:
Making Mercury/cs/test.c
test.m:098: In clause for function `testQAnd'/0:
test.m:098: in argument 1 of call to predicate `solutions'/2:
test.m:098: in unification of argument
test.m:098: and term `Helper(V_34)':
test.m:098: type error in argument(s) of higher-order term (with arity 1).
test.m:098: Functor (Helper) has type `pred(query.query, int)',
test.m:098: expected type was `((func V_13) = V_14)'.
** Error making `Mercury/cs/test.c'.
I don't have a complete answer to your question, but I believe this has something to do with currying the predicate. I wrote some test code which queries a small database of fish.
This helper produces the same error as above:
This helper works fine:
I also tried wrapping the solutions function. This works fine:
I was able to write a predicate that returned a lambda predicate, however I was unable to write a function to do the same. This is where I start to get confused. According to this page it is only possible to return a predicate with mode information if you wrap the predicate in a discriminated union type. The following code isn't really useful, but it manages to both
See:
And then to use it: