这些天我正在研究OCaml并遇到过这个问题:
OCaml限制了它可以放在let rec的右侧。喜欢这个
let memo_rec f_norec =
let rec f = memoize (fun x -> f_norec f x) in
f;;
Error: This kind of expression is not allowed as right-hand side of `let rec'
其中,memoize是一个函数,它接受一个函数并将其转换为带有Hashtable的记忆版本。很显然,OCaml在'let rec'右侧对构造的使用有一些限制,但是我真的不明白,有人能解释一下吗?
答案 0 :(得分:6)
允许受let rec
约束的表达式在本手册的section 7.3中有所描述。具体而言,不允许涉及let rec
定义名称的函数应用程序。
粗略摘要(摘自该链接):
非正式地,接受定义的类包含那些定义的名称仅出现在函数体内或作为数据构造函数的参数的定义。
答案 1 :(得分:3)
您可以使用绑结技术来定义记忆固定点。例如,参见那两个等价的定义:
let fix_memo f =
let rec g = {contents = fixpoint}
and fixpoint x = f !g x in
g := memoize !g;
!g
let fix_memo f =
let g = ref (fun _ -> assert false) in
g := memoize (fun x -> f !g x);
!g
或者使用Alain提醒的lazy
:
let fix_memo f =
let rec fix = lazy (memoize (fun x -> f (Lazy.force fix) x)) in
Lazy.force fix
答案 2 :(得分:0)
https://realworldocaml.org/v1/en/html/imperative-programming-1.html
中的Memoization and Dynamic Programming
部分清楚地说明了这一点