OCaml 中的 @@ 和 |> 运算符优先级

Gue*_*OCs 1 ocaml functional-programming

我正在尝试了解 2 个 OCaml 运算符:@@|>

我明白这x |> f只是f(x),但它为什么存在?我不明白为什么。相同的 for @@,正如我所理解的,只是普通的函数应用程序

例如:

 match get_ipv4_hlen_version buf |> version with
      | 0x40 -> Ok buf
      | n -> Error (Printf.sprintf "IPv4 presented with a packet that claims a different IP version: %x" n)
Run Code Online (Sandbox Code Playgroud)

为什么不写只是get_ipv4_hlen_version version buf

关于什么

let options_len = nearest_4 @@ Cstruct.len t.options
Run Code Online (Sandbox Code Playgroud)

为什么不 let options_len = nearest_4 Cstruct.len t.options

?

我想这与优先级有关,我记得 Haskell 的一些东西,但我不知道 Haskell 我只是在某处读到过。

我怎么知道事物的优先级?

如果需要更多上下文,这两个代码来自https://github.com/mirage/mirage-tcpip/blob/master/src/ipv4/ipv4_packet.ml

Jef*_*eld 6

的符号值|>仅在您有多个嵌套函数应用程序时出现。很多人发现这个:

 x |> f a |> g b c |> h d
Run Code Online (Sandbox Code Playgroud)

比这更容易阅读:

 h d (g b c (f a x))
Run Code Online (Sandbox Code Playgroud)

因为不再需要在心理上匹配括号,并且因为操作是按从左到右的顺序应用的(这对于英语和其他从左到右语言的读者来说可以说是很自然的)。

如果您熟悉 Unix 命令行,那么将|>运算符视为类似于 Unix 管道运算符可能会有所帮助|

较低优先级的函数应用运算符 like@@也有助于避免括号(及其心理匹配)。很多人发现这个:

f x @@ g a b @@ h c d
Run Code Online (Sandbox Code Playgroud)

比这更容易阅读:

f x ((g a b) (h c d))
Run Code Online (Sandbox Code Playgroud)

你@@ 的例子是错误的。这个

let options_len = nearest_4 @@ Cstruct.len t.options
Run Code Online (Sandbox Code Playgroud)

相当于:

let options_len = nearest_4 (Cstruct.len t.options)
Run Code Online (Sandbox Code Playgroud)

并且不等同于您所写的内容。

运算符的优先级由它的第一个字符决定。反过来,这由OCaml 手册第 7.7.1 节中的表格定义。

(当然,您需要非常仔细地阅读表格之前的文本以查看优先规则。)

更新

完全披露:我从不使用|>@@在我自己的代码中。我对几个括号没有问题,我通常let用来将一个大表达式分解成更小的部分。