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

Mar*_*tus 7 f# ocaml

在OCaml或F#中,典型的形式是连续的let绑定:

let a1 = ...
let a2 = ...
let a3 = ...
let f1 = ...
let f2 = ...
let f3 = ... 
f3 a1 a2 a3
Run Code Online (Sandbox Code Playgroud)

在许多情况下,其中一些允许绑定(例如上面示例中的f1f2)仅用作紧跟在它们之后的表达式或函数的构建块,之后不再引用.在其他情况下,确实在"链"的末尾使用了一些值(例如,上述示例中的a1,a2a3).是否存在任何语法习惯用语来明确范围内的这些差异?

jro*_*uie 11

On可以使用它来明确temp仅用于以下定义a1:

let a1 =
  let temp = 42 in
  temp + 2 in
let a2 = ...
Run Code Online (Sandbox Code Playgroud)

范围temp确实仅限于定义a1.

另一个模板是重复使用相同的名称来隐藏它以前的用法,因此也清楚地说明以前的用法是暂时的:

let result = input_string inchan in
let result = parse result in
let result = eval result in
result
Run Code Online (Sandbox Code Playgroud)

但是,重用相同的名称是值得商榷的.

当然一个人总是有评论和空行:

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

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

f3 a1 a2 a3
Run Code Online (Sandbox Code Playgroud)

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

let (|>) x f = f x;;
Run Code Online (Sandbox Code Playgroud)

那你就可以写点东西了

input_string inchan |> parse |> eval |> print
Run Code Online (Sandbox Code Playgroud)

  • 并且,为了稍微扩展,如果`temp`用于计算多个值,你可以将这些值同时绑定为元组:`让a1,a2,a3 =让temp = ... in temp + 2,temp - 2,temp*2` (2认同)
  • 此外,根据RHS上表达式的复杂程度,您可能会考虑"管道"习语(e |> e |> e |> e) (2认同)

Ash*_*wal 7

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

# 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>
Run Code Online (Sandbox Code Playgroud)

使用的一个小例子|>

# [1;2;3]
  |> List.map string_of_int
  |> String.concat "; "
  |> Printf.sprintf "[%s]";;
- : string = "[1; 2; 3]"
Run Code Online (Sandbox Code Playgroud)

你最终需要|-flip更现实的例子.这被称为无默认编程.