多相バリアント

アップキャスト/ダウンキャストのメモ。

# type super = [`a | `b | `c];;
type super = [ `a | `b | `c ]
# type sub = [`a | `b];;
type sub = [ `a | `b ]
# ((`a : sub) :> super);;
- : super = `a
# match (`a: super) with #sub as x -> x | `c -> assert false;;
- : [> sub ] = `a

やはり私は部分範囲型が大好きなんだなあと実感中。Pascalと異なり宣言上で連続している必要が無いのが最高ですね。*1
一方で、もし偶然同じタグを使ったらという恐怖がつきまとっているのも事実。*2 名前空間が無い時代再び感がして微妙に空恐ろしい。タグを宣言させてくださいよ。

module X = struct
  polymorphic_variant_tag `a;
end
module Y = struct
  polymorphic_variant_tag `a
  polymorphic_variant_tag `b of int
end
type t = [X.`a | Y.`a | Y.`b of int]

*1:Pascalでは配列の添え字やループカウンタとしての用途があるので連続している事に意味があるのですが……どうにか導入できないかな。

*2:内部表現はタグ名文字列のハッシュ値(31bit)っぽいですし、ソース上の識別子に気をつけていてもこっちが被るほうの心配もゼロではないですし