ocaml - Prefix_action, suffix_action 带序列
问题描述
我想用 seq (resp suffix_action) 编写一个函数 prefix_action,这是 BatEnum 中的代码:
let prefix_action f t =
let full_action e =
e.count <- (fun () -> t.count());
e.next <- (fun () -> t.next ());
e.clone <- (fun () -> t.clone());
f ()
in
let rec t' =
{
count = (fun () -> full_action t'; t.count() );
next = (fun () -> full_action t'; t.next() );
clone = (fun () -> full_action t'; t.clone() );
fast = t.fast
} in t'
我想知道,因为我们没有序列中的克隆,我想知道在这些情况下我应该如何考虑克隆(它是对序列的使用),如果是这种情况,我们如何才能获得使用顺序? Prefix_action 文档
解决方案
定义的序列没有克隆功能,只是因为它是“默认定义的”。
type 'a node =
| Nil
| Cons of 'a * 'a t
and 'a t = unit -> 'a node
正如你所看到的,它只是一个返回一些 sum 类型的函数,如果你愿意,可以是简单的值,没有副作用(实际上它们可以隐藏在函数体中,但现在让我欺骗你)。因此,这种情况下的克隆函数只是一个身份:
let clone s = s
现在,如果您查看枚举的定义,您会注意到很少的mutable
关键字:
type 'a t = {
mutable count : unit -> int;
mutable next : unit -> 'a;
mutable clone : unit -> 'a t;
mutable fast : bool;
}
如果我们尝试使用与clone
序列相同的方法,我们会注意到一个副本的更改会影响另一个副本:
# let e1 = { fast = true; (* ... *) };;
val e1 : 'a t = {fast = true; (* ... *)}
# let e2 = clone e1;;
val e2 : 'a t = {fast = true; (* ... *)}
# e1.fast <- false;;
- : unit = ()
# e2;;
'a t = {fast = false; (* ... *)}
这就是为什么他们需要clone
功能。
所以现在您可以实现您的功能,例如prefix_action
.
prefix_action f e
将表现为e
但保证将在读取f ()
当前第一个元素之前仅调用一次。e
问题出在这个“恰好一次”上。我不确定它是什么意思,但是可以说这意味着如果您将序列传递给prefix_action f
然后两次传递给hd
,那么f
将只执行一次(因为如果它意味着不同的东西,那就没意思了)。现在我们可以回到这个“副作用”的故事。显然,没有它们我们就无法实施prefix_action
。序列的类型不包含任何mutable
关键字,但它包含函数!因此,我们可以将副作用包装到函数中。
let prefix_action : (unit -> unit) -> 'a t -> 'a t = fun f s ->
let b = ref true in
fun () -> (if !b then f (); b := false); s ()
但是现在,由于我们有副作用,我们需要重新定义clone
. 从规格prefix_action
:
If
prefix_action f e
被克隆,f
在克隆期间仅被调用一次。
因此我们的clone
:
let clone s = let _ = s (); s
推荐阅读
- google-api - G Suite Users:get 和 Users:list 资源不会同时更新
- javascript - 正则表达式中的变量
- quantum-computing - IBMQProvider 问题
- qt - Qml Error: Cannot assign QObject* to QQuickItem
- google-cloud-platform - 如何在活动实例中删除 Google Cloud Compute Engine 实例
- python - Python、openCV 和 filter2D:“错误”结果
- html - 我的反引号 (`) 是 HTML 中引号 (") 的有效替换吗?
- angular - Angular 9 - use of @ContentChildren
- amazon-quicksight - 有没有办法在快速查看日期下拉列表
- angular - Angular Cookie 会话 ID