Ocaml - Lazy.force

Sec*_*ret 5 ocaml functional-programming

我的地图功能是:

type 'a stream = Cons of 'a * 'a stream Lazy.t

let rec ones = Cons(1, lazy(ones));;

let rec map (f:'a -> 'b) (s:'a stream) : 'b stream =
  match s with
  |Cons(h,t) -> Cons(f h, lazy (map f (Lazy.force t)));;
;;
Run Code Online (Sandbox Code Playgroud)

正确?Lazy.强制它就像已经让它记忆了吗?

gas*_*che 7

是的,这是正确的.

但是请注意,在常规/循环而不是无限数据结构(如此ones处)上应用时,不会共享计算.强制N个第一个元素map succ ones仍然会应用succN次.(实际上有一些关于语言的研究工作可以检测这种形式的规律性/周期,并对它们进行严格的映射终止,参见例如CoCaml项目.)


sea*_*mcl 5

在ocaml懒惰类型中有一些魔力.我认为当你自己实现它时,更容易理解懒惰,这很容易,虽然不是语法上方便.技巧是

  • 使用闭包进行延迟评估
  • 使用ref单元来记忆计算

在这里,很清楚Lazy'.force中的记忆是如何以及何时发生的.

module Lazy' : sig
  type 'a t
  val delay: (unit -> 'a) -> 'a t
  val force: 'a t -> 'a
end = struct
  type 'a susp =
  | NotYet of (unit -> 'a)
  | Done of 'a

  type 'a t = 'a susp ref

  let delay f = ref (NotYet f)

  let force f =
    match !f with
    | Done x -> x
    | NotYet f' ->
      let a = f'() in
      f := Done a;
      a
end
Run Code Online (Sandbox Code Playgroud)

输入'a stream ='of a''a stream Lazy'.t ;;

let ones = let rec''(= = Cons(1,Lazy'.delay ones')in ones'();;

让rec map fs =匹配s与| 缺点(h,t) - >缺点(fh,Lazy'.delay(fun() - > map f(Lazy'.force t)));;

  • 第二个间接在'type'at = unit - >'a susp ref`的目的是什么?你只返回`fun() - > r`或在``中使用``s = f().你为什么不能削减中间人?PS:很清楚,我在问为什么http://ideone.com/Eidm34不起作用. (2认同)