3

我正在学习union一点 OCaml,我很困惑。


在 C 中,联合是这样的

union {
    int i;
    float f;
} x;
x.i = 0x27;
printf ("%f\n", x.f);

那么,OCaml 中的 union 是否具有相同的目的?

让我们举个例子。下面是一个联合定义:

在此处输入图像描述

如何像上面的 C 示例一样使用这个联合?


也为这个

在此处输入图像描述

type 'a set联合定义吗?怎么样type 'a set = 'a list?为什么?

4

1 回答 1

8

OCaml 中的可区分联合就像 C 联合与枚举的组合。因此,您的number类型示例可以在 C 中表示如下:

enum number_tag {
    ZERO, INTEGER, REAL
};

union number_value {
    int i; /* Only access this if tag is INTEGER */
    float f; /* Only access this if tag is REAL */
};

struct number {
    enum number_tag tag;
    union number_value value;
};

所以你可以通过访问枚举来询问数字的类型是什么,然后根据枚举的值访问并集的相应字段。当然,C 不会停止访问联合的错误字段。

另一方面,OCaml 消除了访问错误字段的可能性。由于您只能通过模式匹配访问值,因此您知道您始终拥有正确的类型。

类型值的模式匹配number在 OCaml 中如下所示:

match value_of_type_number with
| Zero ->
    (* Handle the case that the number is Zero *)
| Integer i ->
    (* Handle the case that the number is an Integer with the value i *)
| Float f ->
    (* Handle the case that the number is a Float with the value f *)

相当于这样:

switch(value_of_type_number.tag) {
case ZERO:
    /* Handle the case that the number is Zero */
    break;
case INTEGER:
    int i = value_of_type_number.value.i;
    /* Handle the case that the number is an Integer with the value i */
    break;
case FLOAT:
    float f = value_of_type_number.value.f;
    /* Handle the case that the number is a Float with the value f */
    break;
}

type 'a set联合定义吗?怎么样type 'a set = 'a list?为什么?

type 'a set根本不是一个定义。它只是指定接口。它说这个接口的实现必须定义一个名为的类型set,它接受一个类型参数。

type 'a set = 'a list是一个定义,但不是一个受歧视的工会。它只是一个类型别名。那就是说“'a set只是'a list'的另一个名称。可区分联合的定义将有一个构造函数作为等号之后的第一件事。构造函数总是以大写字母开头。

于 2013-01-09T18:25:05.667 回答