2017-01-16 74 views
1

通用TryValue類型的語法是什麼,它可以返回值'a或錯誤'b?f#歧義聯合通用

type TryValue = 
    | Value of 'a 
    | Error of 'b 

如果錯誤是一個字符串,那麼它的罰款:

type 'a TryValue = 
    | Value of 'a 
    | Error of string 

我想定義一個tryRun函數,它接受一個錯誤的創造者,一個功能和參數,將嘗試運行的功能用參數和在任何錯誤使用錯誤創建者函數創建了一個錯誤:

let tryRun createErrorFn param fn = 
    try 
     Value (fn param) 
    with 
     | ex -> Error (createErrorFn ex.Message param) 

而對於任何功能的包裝,以由tryRun包裹:

let wrapTryRun createErrorFn fn param = 
    match param with 
    | Value a -> tryRun createErrorFn a fn 
    | Error e -> Error e 

現在我可以運行的功能列表(僞代碼,還沒有完全制定了這一點):

let createErrorFn errorMessage param = 
    URLProcessignError {url=param.url;errorMessage=errorMessage} 
[fn1;fn2] |> List.fold (fun acc fn -> (wrapTryRun createErrorFn fn acc)) 
+1

看起來像有結果類型在[F#4.1](https://blogs.msdn.microsoft.com/dotnet/2016/07/25/a-peek-into-f-4-1/) – s952163

回答

4

你缺少通用的參數在左側:

type TryValue<'a,'b> = 
    | Value of 'a 
    | Error of 'b 

當只有一個參數時,您可以像使用字符串一樣使用ML樣式,但如果您有多個參數,則應使用帶有尖括號的.NET符號。

2

其實,老ML風格也可以用多種類型的參數,通過指定一個元組使用:

type ('a, 'b) TryValue = 
    | Value of 'a 
    | Error of 'b 

不過,我相信我讀舊的語法已經過時......

+1

我不認爲這是真的被棄用,只是不建議你自己的類型。許多人遵循編譯器通常的輸出語法,對於其他類型的列表和選項以及C#樣式等內置類型,使用ML樣式;我個人更喜歡在任何地方使用C#風格來保持一致性。 – Tarmil

+0

將ML轉換爲F#時,ml樣式派上用場。如果ML風格貶值,則將ML更難轉換爲F#。 –