Closed eazar001 closed 9 years ago
The code below seems to obtain the exact desired behavior I described above earlier. When I get the chance I'll further test it for hitches or any weird cases, and push it with an actual test suite.
lazy_maplist(Goal, Xs, Ys) :-
freeze(Ys, lazy_maplist_(Xs, Ys, Goal)).
lazy_maplist_([], [], _).
lazy_maplist_([X|Xs], [Y|Ys], Goal) :-
call(Goal, X, Y),
lazy_maplist(Goal, Xs, Ys).
I would love to have lazy_maplist/3
. Eventually, I'd like to have lazy variants of all the predicates in library(apply)
Yes, eventually getting all of apply in lazy form would be great. lazy_findall
is also a great idea btw.
Using the nice infrastucture we have, we can do things such as:
... which admittedly isn't so nice after glancing at it a second time. This is because it's doing twice the amount of work. There are nice utilities to counteract this effect, such as
lazy_include/3
for example. In Haskell we can do:This is all done in one pass thanks to the spirit of lazy evaluation that is built into the core functionality of Haskell's main implementation. In the above example
take/3
is not the problem, since it is implemented in terms ofsplit_at/4
which works quite well with lazy lists; it ismaplist/3
that is making things very strict. There are a few ways of addressing this that crossed my mind. One way would be to create alazy_maplist/3
to solve the problem in the spirit of yourlazy_include/3
. Another would be to simply make a variant oftake/3
.... perphaps atake_with/4
oftake_map/4
, which synthesizes a solution frommaplist/3
andtake/3
. Another option is to do both.Either way, I wanted to catalog this issue to serve as a memorandum at the very least.
Of peripheral interest: usingEDIT: I just noticed you implemented this with[0..2]
is very convenient syntax sugar. All the more reason to integrate your lazyincr/3
example intolazy_range/2
for the API.postive_integers/3
.