OCaml Records and Tuples

这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战

Records(记录)

OCaml中的记录很像其他语言中的结构体。下面举个例子,

utop # type ptype = TNormal | TFire | TWater;;
type ptype = TNormal | TFire | TWater

utop # type mon = { name : string; hp : int; ptype : ptype };;
type mon = { name : string; hp : int; ptype : ptype; }
复制代码

我们可以看到定义了一个叫做mon的记录,包含三个字段:namehpptype。并且这些字段的类型都已经确定了。这里有一个点是,ptype不仅是类型名称也是字段名称。

我们可以创建一个mon类型的变量,并且访问其中的字段

utop # let c = { name = "Charmander"; hp = 39; ptype = TFire };;
val c : mon = {name = "Charmander"; hp = 39; ptype = TFire}

utop # c.hp;;
- : int = 39
复制代码

也可以用模式匹配来访问记录的字段

utop # match c with { name = n; hp = h; ptype = t} -> h;;
- : int = 39
复制代码

其中,nht是模式变量。这里有一个语法糖: 如果你想匹配的变量名称和字段的名称相同,可以进行简写:

utop # match c with { name ; hp ; ptype } -> hp;;
- : int = 39
复制代码

Syntax

记录的语法形式上为

{ f1 = e1; ...; fn = en }
复制代码

其中,一个字段访问可以写成

e.f
复制代码

其中f为字段的名称,而不是一个表达式。

这里动态和静态的语义就不过多介绍。

Tuples

和记录一样,元组也是一种组合的数据结构。与记录中需要给字段命名不同的是,元组通过位置来决定。下面有几个元组的例子:

(1, 2, 10)
(true, "Hello")
([1; 2; 3], (0.5, 'X'))
复制代码

元组中只有两个元素为一个匹配(pair)。有三个元素的被称为tripe

超过三个元素的,通常使用记录而不是元组,因为当字段过长记住每个字段所代表的含义会很麻烦。

也可以通过模式匹配来访问元组:

utop # match (1, 2, 3) with (x, y, z) -> x + y + z;;
- : int = 6
复制代码

Variants vs. Tuples and Records

下面说一下 变种与元组和记录的区别

The big difference between variants and the types we just learned (records and tuples) is that a value of a variant type is one of a set of possibilities, whereas a value of a tuple or record type provides each of a set of possibilities. Going back to our examples, a value of type day is one of Sun or Mon or etc. But a value of type mon provides each of a string and an int and ptype. Note how, in those previous two sentences, the word “or” is associated with variant types, and the word “and” is associated with tuple and record types. That’s a good clue if you’re ever trying to decide whether you want to use a variant, or a tuple or record: if you need one piece of data or another, you want a variant; if you need one piece of data and another, you want a tuple or record.

One-of types are more commonly known as sum types, and each-of types as product types. Those names come from set theory. Variants are like disjoint union, because each value of a variant comes from one of many underlying sets (and thus far each of those sets is just a single constructor hence has cardinality one). Disjoint union is indeed sometimes written with a summation operator ΣΣ. Tuples/records are like Cartesian product, because each value of a tuple or record contains a value from each of many underlying sets. Cartesian product is usually written with a product operator, ×× or ΠΠ.

猜你喜欢

转载自juejin.im/post/7032636946346180616