我想寫一些函數,通過返回雙選項而不是雙打來處理錯誤。許多這些函數都會調用eachother,因此需要雙重選項作爲輸入以輸出其他雙重選項。問題是,我不能用雙選項做什麼,我可以用雙打來做 - 這很簡單,就像使用'+'添加它們一樣。F#選項類型執行計算
例如,一個函數將兩個雙精度分開,並返回一個double選項,其中none表示除零誤差。然後另一個函數調用第一個函數,並向它添加另一個雙重選項。
請告訴我是否有辦法做到這一點,或者我完全誤解了F#選項類型的含義。
我想寫一些函數,通過返回雙選項而不是雙打來處理錯誤。許多這些函數都會調用eachother,因此需要雙重選項作爲輸入以輸出其他雙重選項。問題是,我不能用雙選項做什麼,我可以用雙打來做 - 這很簡單,就像使用'+'添加它們一樣。F#選項類型執行計算
例如,一個函數將兩個雙精度分開,並返回一個double選項,其中none表示除零誤差。然後另一個函數調用第一個函數,並向它添加另一個雙重選項。
請告訴我是否有辦法做到這一點,或者我完全誤解了F#選項類型的含義。
這就是所謂的提升 - 你可以寫函數解除另一個函數在兩個選項:
let liftOpt f o1 o2 =
match (o1, o2) with
| (Some(v1), Some(v2)) -> Some(f v1 v2)
| _ -> None
,那麼你可以提供應用例如功能:
let inline addOpt o1 o2 = liftOpt (+) o1 o2
你甚至可以進一步讓代碼更具可讀性:定義liftOpt就像在這裏完成的那樣,然後(這樣做*非常,非常非常本地*)用'let(+)o1 o2 = liftOpt(+)o1 o2'這樣的東西來映射'+'。現在你可以寫'let x,y =一些3.0,一些2.0',然後'x + y'。 –
@DanielFabian良好的提示,偉大的地方(國際海事組織)要做到這一點將是提升'(+)'在'模塊選項',以擴大默認的'選項'。然後,只有在「打開選項」之後,您才能將範圍內的(+)提升 –
最後,我意識到我真正想要的是Option.get函數,它只需要一個'選項並返回'a。這樣,我可以模式匹配,並返回我想要的值。
liftA2
如上所述將提供一種通用方法來將可用於參數double
參數的任何函數「提升」到可在double option
參數上工作的函數。
然而,在你的情況,你可能必須編寫特殊的功能你自己來處理你提到的邊緣情況
let (<+>) a b =
match (a, b) with
| (Some x, Some y) -> Some (x + y)
| (Some x, None) -> Some (x)
| (None, Some x) -> Some (x)
| (None, None) -> None
注意liftA2
不會把您想在自動添加None
到Some(x)
案件。
的鴻溝liftA2
方法還需要一些特殊的處理,但其結構通常是什麼我們會自己寫
let (</>) a b =
match (a, b) with
| (Some x, Some y) when y <> 0.0d -> Some (x/y)
| _ -> None
您可以使用這些功能,如
Some(2.0) <+> Some(3.0) // will give Some(5.0)
Some(1.0) </> Some(0.0) // will give None
而且,嚴格地說, lift
被定義爲「高階函數」 - 這是一個函數並返回另一個函數的東西。
因此,這將是這個樣子:
let liftOpt2 f =
(function a b ->
match (a, b) with
| (Some (a), Some (b)) -> f a b |> Some
| _ -> None)
在這種情況下,你可能要考慮Nullables以上選項,原因有二:
嘗試添加一些代碼示例,說明您要實現什麼,以及出現什麼錯誤 – Petr
Some(1.0)+ Some(1.0)不起作用。如果它真的不起作用,那麼我不能真正使用它,因爲我有很多功能需要雙重選擇並返回雙重選項,並且他們都依靠彼此來做一些數學運算。 – user3685285
你正在尋找的是一個選項工作流程。看看[這個線程](http://stackoverflow.com/questions/7818277/is-there-a-standard-option-workflow-in-f)。 – scrwtp