懒惰的比较功能组合

时间:2018-01-13 18:04:15

标签: ocaml lazy-evaluation

我想撰写几个compare函数应用程序。一种天真的方法是:

let (>>==): int -> int -> int  = fun a b -> if a = 0 then 0 else b

type c = {f1 : bool; f2: int; f3: bool;  f4: int; unused: int}

let compare (a:c) (b:c) =
  compare a.f1 b.f1  >>==
  compare a.f2 b.f2  >>==
  compare a.f3 b.f3  >>==
  compare a.f4 b.f4

但是,所有这些都将被评估,即使第一个返回0并且不需要进一步评估。如果有办法懒洋洋地这样做,最好保留中缀语法?

1 个答案:

答案 0 :(得分:1)

由于OCaml是一种急切的语言,因此在函数调用之前会计算函数的参数。您希望懒惰地评估>>==函数的第二个参数,并且获得此函数的唯一方法是使用lambdas或等效的内置惰性支持。

你可以这样编写你的函数:

let (>>==) a bl =
    if a = 0 then 0 else bl ()

并称之为:

let lcompare (a:c) (b:c) =
    compare a.f1 b.f1 >>==
    (fun () -> compare a.f2 b.f2)  >>==
    (fun () -> compare a.f3 b.f3)  >>==
    (fun () -> compare a.f4 b.f4)

或者你可以使用内置的懒惰设施:

let (>>==) a bl =
    if a = 0 then 0 else Lazy.force bl

let lcompare (a:c) (b:c) =
    compare a.f1 b.f1 >>==
    lazy (compare a.f2 b.f2)  >>==
    lazy (compare a.f3 b.f3)  >>==
    lazy (compare a.f4 b.f4)

可能有更优雅的方式来设置定义,但我相信这是基本问题。