什么是| ocaml 中的符号是什么意思?

What does the | symbol mean in ocaml?

我查看了 O'Caml 文档,但仍然想知道,| 符号是什么意思或作用?

这是一个使用它的地方的例子:

(function (0, 0) -> "both zero"
          | (0, _) -> "first only zero"
          | (_, 0) -> "second only zero"
          | (_, _) -> "neither zero")

但显然我不认为这包含它的所有用途。

这是pattern matching(或者用更像数学的语言说的“案例分析”)。 OCaml 最基本的功能之一。

ASCII 符号| 用于分隔分句。它表示 case 的析取,让人联想到 ||,它是布尔析取运算符。

此处它与关键字 function 一起使用,这意味着您构建一个闭包,无需首先命名它即可立即对其参数(一对整数)进行模式匹配。


custom sum types 的定义遵循类似的语法,用于类比模式匹配。示例:

(* definition of a sum type
   whose values are EITHER [None] OR [Some_int x]
   where x is an integer: *)
type int_option =
  | None
  | Some_int of int

(* pattern matching on a value of type [int_option]: *)
let add (x_opt : int_option) (y : int) : int =
  match x_opt with
  | None       -> y
  | Some_int x -> x + y

functionmatch ... with之后出现了一系列pattern/expressions对。 | 符号用于将这些对彼此分开。

在每一对中,模式和表达式依次由 -> 分隔。

在一个模式中 | 可用于分隔备选子模式。

match x with
| (1 | 3 | 5 | 7) -> "odd"
| _ -> "even"

正如其他评论者指出的那样,| 也可以与其他字符组合形成运算符名称。也就是说,OCaml 名称(对于值)可以包含特殊字符,例如 |>+,如果您以正确的方式定义它们的话。 (唯一真正的问题是它们需要在定义中用括号括起来。)

在OCaml中,|用于分隔OR-patterns or to separate constructors in a type definition. Patterns in OCaml are ubiquitous and is one of the most important and beautiful feature of the language that complements another feature, Algebraic Data Types中的大小写。

定义了代数数据类型inductively as a set of formation rules。例如,我们可以为矩形、圆形、它们的组合或换位的图形定义一个类型,例如

type figure = 
  | Rectangle of int * int 
  | Circle of int
  | Composition of figure * figure
  | Transposition of figure

上面的类型定义了一组无限可能的图形。模式可以轻松分析它们的结构。在没有模式的语言中,我们不得不依赖动态转换和 if/then/else.

事实上,您可以将模式视为对所有语言通用的 if/then/else 分支工具的概括。在 if/then/else 中,我们正在解构布尔值,它只有两种情况,truefalse。此外,truefalse 值不包含任何附加信息。基本上,truefalse 的含义由其名称定义,仅此而已。我们的数字示例不同,我们定义的每个案例都包含我们想要访问的额外信息,例如

let rec area f = match f with
  | Rectangle (w,h) -> w * h
  | Circle r -> 2*r*r + 2*r + 1
  | Composition (l,r) -> area l + area r
  | Transposition f -> area f

我们可以看到,我们的 match 表达式就像一个三向 if/then/else ,它还将每个图形向下转换为其匹配类型,并可以轻松访问每个图形的属性,以便我们可以计算它们占据的像素数。在缺少模式匹配的语言中,我们将不得不依靠 visitor pattern 来计算图形的面积。

我们还可以注意到,数据类型的定义是如何与模式匹配表达式相吻合的。确实,如果定义声明了数据类型是如何构造的,那么模式匹配就定义了数据类型是如何解构的。

此外,作为奖励曲目,语法,

let foo = function X -> a | Y -> b

的语法糖
let foo v = match v with X -> a | Y -> b