I was motivated by your speach to try it out for myself:
p(0,1).
q(1,2).
r(2,3).
s(1,3,4).
test003(START,RESULT) --> [PRED], { CALL=..[call,PRED,START,VALUE2], call(CALL)}, ({RESULT=VALUE2};test003(VALUE2,RESULT)).
/*
(ins)?- phrase(test003(0,RES), [p,q,r,s(1)],R).
RES = 1,
R = [q, r, s(1)] ;
RES = 2,
R = [r, s(1)] ;
RES = 3,
R = [s(1)] ;
RES = 4,
R = [] ;
false.
*/
:- use_module( library(edcg)).
edcg:acc_info(monad,PRED,In,Out,(CALL=..[call,PRED,In,Out],call(CALL))).
edcg:pred_info(test004,0,[dcg,monad]).
test004 -->> [PRED], !, [PRED]:monad, test004.
test004 -->> [].
/*
(ins)?- test004([p,q,r,s(1)],X,0,E).
X = [],
E = 4.
(ins)?- test004([p,q,r],X,0,E).
X = [],
E = 3.
(cmd)?- test004([p,q],X,0,E).
X = [],
E = 2.
(cmd)?- test004([p],X,0,E).
X = [],
E = 1.
(cmd)?- test004([],X,0,E).
X = [],
E = 0.
*/
edcg:pred_info(test005,0,[dcg,monad]).
test005 -->> [PRED], [PRED]:monad, test005.
test005 -->> [].
/*
(cmd)?- test005([p,q,r,s(1)],X,0,E).
X = [],
E = 4 ;
X = [s(1)],
E = 3 ;
X = [r, s(1)],
E = 2 ;
X = [q, r, s(1)],
E = 1 ;
X = [p, q, r, s(1)],
E = 0.
*/
edcg:pred_info(test006,0,[dcg,monad]).
test006 -->> [].
test006 -->> [PRED], [PRED]:monad, test006.
/*
(cmd)?- test006([p,q,r,s(1)],X,0,E).
X = [p, q, r, s(1)],
E = 0 ;
X = [q, r, s(1)],
E = 1 ;
X = [r, s(1)],
E = 2 ;
X = [s(1)],
E = 3 ;
X = [],
E = 4.
*/
(It is maybe not the full flavor of a monad, just a pipe, but also a good exercise.)
Edcg is indeed better readable than dcg.
Btw. is in dcg any possibility to enclose the list by another cons cell when I call another dcg predicate?
Normally I would write something like:
x ā [A,B], {ā¦}, y.
If R is the remaining list, y operates on R, but I want that y operates for instance on [A|R].
Is that possible?
Kind regards.