我正在編寫一個程序,在該程序中我必須驗證obj類型的某些輸入爲數字類型。基本上,我在找寫功能F#數值類型鑄造
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,然後第二個和更高版本的匹配個案輸入錯誤。我想我可以通過爲每個數字類型添加一個額外的數據類型來避免這種情況,但是這感覺像一個醜陋的黑客。有沒有更優雅的解決方案?
謝謝。作爲一個後續問題,寫這個函數時沒有類型註釋,這在F#中是不可能的,或者在函數語言中是不可能的。我試圖理解爲什麼這個函數會失敗(無論是在原始形式還是當例如在^ a:(靜態成員op_Explicit:^ a - >'b))時添加註釋^ a - >'b)。 – Bram
@Bram在F#中,不能直接將泛型函數作爲參數傳遞(以便您可以在不同類型中調用它)。這在其他一些語言中是可能的 - 您也可以在F#中實現這一點,但是您必須將它作爲由對象表達式實現的接口傳遞(因此它會變得有點難看)。 –