osiire’s blog

ふしぎなそふとやさん

多相バリアントと型フィルター

多相バリアントってとても簡潔に便利なので、すぐに「次の要望」が出て来てしまう。例えば、型のフィルターが欲しい。

# 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>