多相バリアントと型フィルター
多相バリアントってとても簡潔に便利なので、すぐに「次の要望」が出て来てしまう。例えば、型のフィルターが欲しい。
# type x = [`A | `B];; type x = [ `A | `B ] # let filter = function #x -> true | _ -> false;; val filter : [> x ] -> bool = <fun> # let f lst = List.filter filter lst val f : ([> x ] as 'a) list -> 'a list = <fun>
最後の関数fはx listしか返さないはずだから、戻り値はx listになって欲しい。でも実際には[> x] listにしかならない。コアーションも出来ない。もちろん、List.filterを使わずに毎回再帰を使ってコアーションしながらfを定義すればいいんだけど、ここはcamlp4の出番ですかね?
#let rec filter = function [] -> [] | hd :: tl -> match hd with #x as x -> (x :> x) :: (filter tl) | _ -> filter tl;; val filter : [> x ] list -> x list = <fun>