什么是OCaml中的`union`,真的

时间:2013-01-09 18:08:15

标签: functional-programming ocaml

我正在学习OCaml的union位,我感到非常困惑。


在C中,联合就像这样

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

那么, OCaml中的联合是否也有同样的目的?

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

enter image description here

如何使用此联合,就像上面的C示例一样?


也是这个

enter image description here

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

1 个答案:

答案 0 :(得分: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'的另一个名称。一个有区别的联合的定义会有一个构造函数作为等号后的第一个东西。构造函数总是以大写字母开头。