OCaml - 如何使用函数创建函数作为输出?

gen*_*xyz 1 ocaml function

"编写一个函数lv: cfg -> (blabel -> ide set),计算给定控制流图上的实时变量分析."

拥有cfgblabel定义并ide set作为字符串列表,如何创建具有该签名的函数?

Gil*_*il' 5

您可能熟悉let定义函数的语法:

let f x = x + 1 in …
Run Code Online (Sandbox Code Playgroud)

您可以在任何地方使用此语法,包括在函数体中.现在,如果您碰巧使用内部函数的名称作为外部函数的返回值,则外部函数将返回一个函数.

let outer_function x =
  let inner_function y = x + y in
  inner_function
Run Code Online (Sandbox Code Playgroud)

let语法其实语法糖funfunction.特别是,如果您inner_function只定义一次使用该名称,您也可以使用该fun表示法而不是为内部函数赋予名称.

let outer_function x =
  fun y -> x + y
Run Code Online (Sandbox Code Playgroud)

此外,如果所有外部函数在传递它时都会执行,则参数是构建并返回内部函数,然后在传递该函数两个参数时考虑其行为.首先,外部函数使用其第一个(也是唯一的)参数构建内部函数; 那个内部函数应用于第二个参数,所以它的主体被执行.这相当于只有一个带有两个参数的函数.这种观察被称为currying.

let outer_function x y = x + y
Run Code Online (Sandbox Code Playgroud)

注意这个函数的类型是int -> int -> int; 这与int -> (int -> int)(箭头类型运算符是右关联)类型相同.

当外部函数在构建内部函数之前执行某些操作时,Currying不适用.在这种情况下,工作在收到第一个参数后执行.

let outer_function x =
  print_endline "outer";
  fun y -> print_endline "inner"; x + y
Run Code Online (Sandbox Code Playgroud)

所以代码的结构可能如下所示:

let lv (c : cfg) : blabel -> ide set =
  let c' = do_some_precomputation c in
  fun (bl : blabel) -> (… : ide set)
Run Code Online (Sandbox Code Playgroud)