[m-users.] Returning a predicate from a function

Tomas By tomas at basun.net
Fri Dec 23 02:13:46 AEDT 2022


On Thu, 22 Dec 2022 12:52:52 +0100, Mark Clements wrote:
> main(!IO) :-
>     test1(!IO), % OK
>     test2(!IO). % Does not compile
> 
> :- pred test1(io::di, io::uo) is det.
> test1(!IO) :- 
>     Data = (pred(Y::out) is nondet :- nondet_member(I,range(1,5)), Y = float(I)), % some data
>     LnData = (pred(Y::out) is nondet :- Data(X), Y = math.ln(X)), % a transformation
>     aggregate(LnData, print_line, !IO).
> 
> :- pred test2(io::di, io::uo) is det.
> test2(!IO) :- 
>     Data = (pred(Y::out) is nondet :- nondet_member(I,range(1,5)), Y = float(I)), % some data
>     LnData = f_ln(Data), %% This transformation does not compile:(
>     aggregate(LnData, print_line, !IO).
> 
> :- func f_ln(pred(float)::(pred(out) is nondet)) = (pred(float)::(pred(out) is nondet)).
> f_ln(Pred) = (pred(Y::out) is nondet :- Pred(X), Y is math.ln(X)).


I'm not 100% sure what you mean for this to do. In particular I am not
sure what "aggregate" does (in Python I assume).

Some general points: maths is not nondet; the basic data structure is
a list. not some abstract generator as in some other languages that I
could mention; you do not always need all these declarations.

This seems to work:


|:- module test.
|
|:- interface.
|:- import_module io.
|:- pred main(io::di, io::uo) is det.
|
|:- implementation.
|:- import_module int, float, list.
|:- use_module math.
|
|main(!IO) :-
|  test1(!IO),
|  test2(!IO).
|
|:- pred test1(io::di, io::uo) is det.
|
|test1(!IO) :- 
|  Data = map(float,1..5),
|  LnData = map(math.ln,Data),
|  write_list(LnData,"",print_line,!IO).
|
|:- pred test2(io::di, io::uo) is det.
|
|test2(!IO) :- 
|  Data = map(float,1..5),
|  LnData = map(f_ln,Data),
|  write_list(LnData,"",print_line,!IO).
|
|:- func f_ln(float::in) = (float::out) is det.
|
|f_ln(F0) = F :- F = math.ln(F0).
|
|:- end_module test.


Is this what you meant?

/Tomas


More information about the users mailing list