代码之家  ›  专栏  ›  技术社区  ›  Eli

在OCaml中保证函数返回值的赋值

  •  6
  • Eli  · 技术社区  · 15 年前

    从Lisp来到OCaml,我发现自己对函数何时返回和何时不返回感到非常困惑。我错过了我的神奇引用!谢天谢地,大多数时候,OCaml似乎自动知道何时需要对函数求值,何时不需要求值。

    let start = Sys.time in
    (*
     * do something here
     *)
     ;
    let ending = Sys.time in
    Printf.printf "did something in %f seconds\n" (ending -. start)
    

    但随后奥坎尔克抱怨道

    Error: This Expression has type unit -> float
           but an expression was expected of type float
    

    告诉我开始和结束 Sys.time ,而不是 系统时间

    这是我想要的行为吗?我想换一种方式做事吗?我是不是错过了一些显而易见的东西?

    3 回复  |  直到 15 年前
        1
  •  10
  •   sepp2k    15 年前

    将函数应用于参数时会对其求值。也就是说,当你 f , f 从不接受评估。当你这么做的时候 f x , f

    Sys.time unit -> float )以及 let start = Sys.time 只是把这个函数分配给 start

    为了得到你想要的行为 let start = Sys.time () ,应用函数 系统时间 () (这是类型的唯一值 unit ).

        2
  •  3
  •   Chuck    15 年前

    unit 论点,即你应该写 Sys.time () 实际应用函数并得到结果 float 价值观。

        3
  •  0
  •   winitzki    14 年前

    为了帮助习惯Lisp的人,我想说OCAML中只有两个求值规则:

    • 延迟评估规则 fun x -> body ,当不应用于任何参数时,将不会进一步求值。(函数体的计算被延迟)相反,表达式体被编译成计算机代码。该计算机代码是函数表达式的实际值,只要函数应用于参数,代码就会运行。
    • :在评估中 f x ,论点 x 首先进行评估。(函数渴望计算它们的参数。)然后函数表达式 f 趣味x->身体 body 尚未计算;只计算得到函数值的值 . 例如, f 身体 评估方式 替换为参数的计算值)。

    因此,如果要延迟某个表达式的求值,可以在OCAML中实现“quote”,只需将其放入函数表达式的主体中。例如,如果您以前计算过 通过 let f = fun x->x+1 现在你想推迟评估 f 3 f 3级 进入函数体:

     let delay_f () = f 3;;
    

    现在你只有在评估的时候才会得到4分 delay_f () delay_f f 3级 在有人评估之前不会被评估 延迟\u f()

    推荐文章