一个指向自身的功能

时间:2011-01-08 23:04:33

标签: ocaml

我在第106页的以下示例中丢失了标题为使用Objective Camel开发应用程序的书。

let nil_assoc = function x -> raise Not found ; ;
let l = ref nil_assoc;;
let add_assoc_again (k,v) l = l := (function x -> if x=k then v else !l x) ; ;
add_assoc_again ('1',1) l ; ;
add_assoc_again ('2',2) l ; ;

l的结果值是一个指向自身的函数,因此循环。

我原以为add_assoc_again ('1', 1) l ;;之后l的值是 功能

x -> if x = '1' then 1 else nil_assoc x;;

继续,add_assoc_again ('2', 2) l ;;之后l的结果值应为 功能

x -> if x ='2' then 2 else ( function x -> if x = '1' then 1 else nil_assoc x ) x;;

我不明白为什么l的结果值是一个指向自身的函数,因此程序挂起并循环

2 个答案:

答案 0 :(得分:3)

当您调用!l时,

add_assoc_again不会被评估,当您调用该调用创建的函数时会对其进行评估。此时l将指向该函数,这就是为什么你得到无限循环。

答案 1 :(得分:2)

新书http://caml.inria.fr/pub/docs/oreilly-book/ocaml-ora-book.pdf中对此代码进行了略微修改,我觉得更清楚:

let nil_assoc = function x -> raise Not_found ;;
let add_assoc (k,v) l = function x -> if x = k then v else l x ;;
val add_assoc : 'a * 'b -> ('a -> 'b) -> 'a -> 'b = <fun>

参数l显然是('a -> 'b)签名中的函数add_assoc,因此,在被调用之前(if测试失败时)不会对其进行求值。 / p>

代码继续:

# let l1 = add_assoc (1, 1) nil_assoc;;

此处l1相当于fun x -> if x = 1 then 1 else nil_assoc x

# let l2 = add_assoc (2, 2) l1;;

l2fun x -> if x = 2 then 2 else (fun y -> if y = 1 then 1 else nil_assoc y) 2

与您提供的版本相比,这一点非常简单。