我想要做的是使用中綴fmap(我定義爲< ^>)爲多種類型工作,如Option和Either(自定義類型)。F#針對多種類型的常見中綴運算符(fmap,applicative,bind等)
考慮:
type Either<'a, 'b> = Left of 'a | Right of 'b
在代碼中,我希望能夠做到:
let fO (a : int option) = None
let fE (a : Either<string,int>) = Left "dummy"
let mO = Some 1
let mE = Right 1
let testO = f0 <^> m0
let testE = fE <^> mE
其中每個(< ^>):
let (<^>) f m = match m with | Some a -> Some <| f a | None -> None
let (<^>) f m = match m with | Right a -> Right <| f a | Left a -> Left a
要獲得選項< ^>工作我已擴展模塊:
namespace Microsoft.FSharp.Core
[<AutoOpen>]
module Option =
let (<^>) f m = match m with | Some a -> Some <| f a | None -> None
[<assembly:AutoOpen("Microsoft.FSharp.Core")>]
do()
以及針對:
type Either<'a, 'b> = Left of 'a | Right of 'b with
static member (<^>) (f,m) = match m with | Right a -> Right <| f a | Left a -> Left a
這幾乎工程,但只有一個可以在同一時間使用。 任一模塊也可以附加到FSharp.Core,但同樣你也只能有一個或另一個。
我知道這可以用2個自定義類型完成,比如Either和Maybe(Haskell選項),但是我會堅持使用Option。
歡迎任何和所有建議。
我沒有足夠的經驗來回答您的主要問題,但你是否知道F#的['Choice'型]的(https://msdn.microsoft.com /en-us/visualfsharpdocs/conceptual/core.choice%5B't1,'t2%5D-union-%5Bfsharp%5D)?這是與'Either'等價的內置等價物。或者,如果Left表示「失敗」的情況,而Right表示「成功」的情況,那麼F#等價物就是['Result'類型](https://github.com/fsharp/fslang-design/blob/master/FSharp -4.1/FS-1004-result-type.md),自F#4.1開始提供。 – rmunn
你可能想看看[F#+](https://github.com/gusty/FSharpPlus),它已經這樣做了,儘管''fmap''的運算符是''<< |''( FParsec中使用相同的運算符)。您還將''綁定爲''>> =''和應用程序''''和''<*>''。如果你看源代碼,你會看到它是如何實現的,這是對@TheInnerLight – Gustavo
@Gustavo答案在下面的答案中解釋的技術的改進好點,我已經添加到我的答案。 – TheInnerLight