Played with lenses in Prolog. Lenses are a kind of microscope that allows you to scale the structure and do some reading or writing in functional mode. Basically, my starting point is the following simulation of setters and declarative getters in Prolog:
Getter: Just <closure>,
called call(<closure>, X, Y), it will extract the value Yfrom X.
Declarative setter: The same <closure>, but used with a different reality,
is called call(<closure>, X, Y, Z), it will update with a Xnew value Y, giving a new one Z.
I quickly came to the definition of the lens composition operator @, which can be used to combine two lenses into a new one, only based on their closures. An example and definition are given in the appendix. But in accordance with this article, lenses can be made simply composite.
In my opinion, when something is composite, it can be easily modeled using DCG. I can do this for a getter as follows, but I have not yet defined a way to do this for a declarative setter:
@(C1, C2)
call(C1),
call(C2).
How would I simulate the setter composition in DCG? Is it possible, perhaps, a change in internal assumptions about how getters and declarative setters are modeled so that the result is simply composite?
Regards
Appendix: Here is an example of some setters and getters:
back(bicycle(X, _), X).
front(bicycle(_, Y), Y).
circumference(wheel(X, _), X).
spokes(wheel(_, Y), Y).
back(bicycle(_, Y), X, bicycle(X, Y)).
front(bicycle(X, _), Y, bicycle(X, Y)).
circumference(wheel(_, Y), X, wheel(X, Y)).
spokes(wheel(X, _), Y, wheel(X, Y)).
Here is a lens composition simulation:
:- op(600, xfy, @).
@(C1, C2, X, Y) :-
call(C1, X, H),
call(C2, H, Y).
@(C1, C2, X, Y, Z) :-
call(C1, X, H),
call(C2, H, Y, J),
call(C1, X, J, Z).
:
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.16)
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam
?- call(front@spokes, bicycle(wheel(1330, 12), wheel(1440, 16)), X).
X = 16.
6 ?- call(back@circumference, bicycle(wheel(1330, 12), wheel(1440, 16)), X).
X = 1330.
7 ?- call(front@circumference, bicycle(wheel(1330, 12), wheel(1440, 16)), 1420, X).
X = bicycle(wheel(1330, 12), wheel(1420, 16)).