obj 型の入力を数値型に検証する必要があるプログラムを作成しています。基本的に、私は関数を書きたいと思っています
validateint : obj -> int option
validatefloat : obj -> float option
... and so on
たとえば、これ自体は問題ではありません。たとえば、次のようなものがあります。
let validateint x =
match x with
| y when y.GetType() = typeof<int> -> y :?> int |> Some
| y when y.GetType() = typeof<float> -> y :?> float |> int |> Some
| y when y.GetType() = typeof<System.Int16> -> y :?> System.Int16 |> int |> Some
/// ...more numeric cases
| _ -> None
ただし、validateint の同様のコードを作成した後、次のようなキャスト関数を入力として受け取る関数を除外することを考えました。
let validatenumeric cast x =
match x with
| y when y.GetType() = typeof<int> -> y :?> int |> cast |> Some
| y when y.GetType() = typeof<float> -> y :?> float |> cast |> Some
| y when y.GetType() = typeof<System.Int16> -> y :?> System.Int16 |> cast |> Some
/// ...more numeric cases
| _ -> None
そして定義する
let validateint = validatenumeric int
let validatefloat = validatenumeric float
...
ただし、F# は基本的にキャストの型を int -> 'a と推測し、2 番目以降の一致ケースが正しく型付けされないため、これは機能しません。すべての数値型を浮動小数点数に追加キャストすることで、これを回避できると思いますが、それは醜いハックのように感じます。よりエレガントなソリューションはありますか?