OCaml如何通过文本表示对多态变体进行排序?

时间:2018-04-08 03:53:24

标签: ocaml

在OCaml中,通过遍历由immediates和指向块的指针组成的值的运行时表示来实现多态比较。

根据Real World Ocaml,没有参数的多态变体只是存储为未装箱的整数。为方便起见,此处摘录。

  

没有任何参数的多态变体存储为未装箱   整数,所以只占用一个字的内存,就像一般   变种。通过应用散列函数来确定该整数值   到变体的名称。哈希函数不直接暴露   由编译器提供,但Core提供的type_conv库提供了一个   替代实施:......

然而,多态比较似乎不对整数值起作用,并且似乎尊重多态变体 name 的词典排序(至少在顶层)。< / p>

# List.sort Pervasives.compare
     [ `L ; `K ; `J ; `I ; `H ; `G ; `F ; `E ; `D; `C ; `B; `A ];; 
[`A; `B; `C; `D; `E; `F; `G; `H; `I; `J; `K; `L]

有一个小皱纹:表示的长度似乎在排序中最重要。

# List.sort compare  [ `BBBB; `AAAA; `AAA; `ABA; `BB; `ZZ; `AA ];; 
[`AA; `BB; `ZZ; `AAA; `ABA; `AAAA; `BBBB]

OCaml如何解决这个问题? OCaml如何在运行时按字典顺序对变体进行排序?不具有任何参数的多态变体不应该与普通整数无法区分吗?

OCaml实施者是否选择了哈希函数,通过巧合/设计,对短变体名称有这种行为?

1 个答案:

答案 0 :(得分:7)

由于它的构造,哈希函数保留了短字符串的顺序。但这不是一般属性。

# List.sort compare [`AAAAAAA; `BAAAAAA; `CAAAAAA];;
- : [> `AAAAAAA | `BAAAAAA | `CAAAAAA ] list =
       [`BAAAAAA; `CAAAAAA; `AAAAAAA]
#

对于OCaml 4.06.0,

的散列代码如下所示
CAMLexport value caml_hash_variant(char const * tag)
{
  value accu;
  for (accu = Val_int(0); *tag != 0; tag++)
    accu = Val_int(223 * Int_val(accu) + *((unsigned char *) tag));
#ifdef ARCH_SIXTYFOUR
  accu = accu & Val_long(0x7FFFFFFFL);
#endif
  /* Force sign extension of bit 31 for compatibility between 32 and 64-bit
     platforms */
  return (int32_t) accu;
}

在我看来,对于代码小于223的短字符串,这将倾向于保留词汇顺序。