在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实施者是否选择了哈希函数,通过巧合/设计,对短变体名称有这种行为?
答案 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的短字符串,这将倾向于保留词汇顺序。