【发布时间】:2016-05-29 13:14:21
【问题描述】:
在 Prolog 中玩镜头。镜头是一种显微镜,可以放大结构并以功能方式进行一些读取或写入。基本上我的出发点是 Prolog 中的 setter 和声明式 getter 的以下建模:
Getter:只是一个<closure>,
称为call(<closure>, X, Y),
这将从X 检索值Y。
声明性 Setter: 相同的 <closure>,但使用不同的 arity,
称为call(<closure>, X, Y, Z),这将通过新值Y 更新X,从而提供新的Z。
我很快就定义了一个镜头合成运算符@,它可以用来将两个镜头组合成一个新镜头,只是基于它们的闭包。附录中提供了示例和定义。但是根据这个article,镜头可以制作成简单的构图。
在我看来,当某事物具有组合性时,它可以通过 DCG 轻松建模。我可以为 getter 执行此操作,如下所示,但我还没有找到一种方法来为声明式 setter 执行此操作:
/* Getter composition as DCG */
@(C1, C2) -->
call(C1),
call(C2).
如何在 DCG 中为二传手组合建模?这是否可能,也许会改变对 getter 和声明性 setter 的建模方式的初始假设,从而使结果只是组合式的?
最好的问候
附录: 下面是一些 setter 和 getter 的示例:
/* getter */
back(bicycle(X, _), X).
front(bicycle(_, Y), Y).
circumference(wheel(X, _), X).
spokes(wheel(_, Y), Y).
/* setter */
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)).
这是镜头构图的建模:
:- op(600, xfy, @).
/* getter composition */
@(C1, C2, X, Y) :-
call(C1, X, H),
call(C2, H, Y).
/* setter composition */
@(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)).
【问题讨论】:
-
哇,是啊,标签镜头很多!
标签: functional-programming prolog composition dcg lenses