OCaml,F#连续,级联让绑定

时间:2012-08-08 21:01:54

标签: f# ocaml

在OCaml或F#中通常以以下形式进行连续的let绑定:

let a1 = ...
let a2 = ...
let a3 = ...
let f1 = ...
let f2 = ...
let f3 = ... 
f3 a1 a2 a3

在许多情况下,其中一些让绑定(例如上面示例中的 f1 f2 )仅用作表达式或函数的构建块,紧跟在它们之后之后再没有引用。在其他情况下,某些值确实在“链”的末尾使用(例如,上面示例中的 a1 a2 a3 )。是否存在任何语法习惯用语来明确范围内的这些差异?

2 个答案:

答案 0 :(得分:11)

开启可以使用它来明确temp仅用于a1的定义:

let a1 =
  let temp = 42 in
  temp + 2 in
let a2 = ...

temp的范围确实仅限于a1的定义。

另一个模板正在重复使用相同的名称来隐藏其先前的用途,因此也明确表示以前的使用是暂时的:

let result = input_string inchan in
let result = parse result in
let result = eval result in
result

重用相同的名称是值得商榷的。

当然,总会有评论和空行:

let a1 = ...
let a2 = ...
let a3 = ...

(*We now define f3:*)
let f1 = ...
let f2 = ...
let f3 = ...

f3 a1 a2 a3

编辑:正如fmr所指出的,我也喜欢管道操作员。它在OCaml中没有默认定义,使用

let (|>) x f = f x;;

然后你可以写点像

input_string inchan |> parse |> eval |> print

答案 1 :(得分:7)

除了jrouquie的答案,你可以通过明智地使用函数组合和其他组合器来避免给中间值命名。我特别喜欢Batteries提供的以下三个:

# let ( |> ) x f = f x;;
val ( |> ) : 'a -> ('a -> 'b) -> 'b = <fun>
# let ( |- ) f g x = g (f x);;
val ( |- ) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c = <fun>
# let flip f x y = f y x;;
val flip : ('a -> 'b -> 'c) -> 'b -> 'a -> 'c = <fun>

使用|>的一个小例子是

# [1;2;3]
  |> List.map string_of_int
  |> String.concat "; "
  |> Printf.sprintf "[%s]";;
- : string = "[1; 2; 3]"

在更实际的示例中,您最终需要|-flip。这称为point-freetacit编程。