2016-12-24 66 views
2

我可以使用管道運算符的模塊和靜態成員函數的函數。我可以在非靜態成員函數中使用它嗎?具有成員函數的管道運算符

我的類:

type MyClass = 
    class 
     new() = {} 

     member this.isZero(number: int): bool = 
      number = 0 

     static member returnInt(): int = 
      33 
    end 

使用靜態成員:

MyClass.returnInt() |> Console.WriteLine // prints 33 

使用非靜態成員:

let foo = new MyClass() 
foo.isZero(2) |> Console.WriteLine // prints false 

我想使用非靜態函數從我目的。語法無效:

let foo = new MyClass() 
foo |> member MyClass.isZero(2) |> Console.WriteLine 

我想使用F#的清晰語法。

+2

你想要實現的代碼是「使用非靜態成員「不行? 'member'永遠不會在實際的成員聲明中使用。 – TeaDrivenDev

+4

我認爲OP正在試圖做到這一點:https://fslang.uservoice.com/forums/245727-f-language/suggestions/5663326-syntax-for-turning-properties-into-functions不,不可能,這是不可能的。在你的例子中,做'foo.isZero(2)'有什麼問題? –

回答

3

如果您已經有實例的標識符,例如foofoo.isZero(2) |> ...是簡短易讀的。在較長的管道中,使用lambda表達式:

funcThatReturnsMyClass(...) |> fun m -> m.isZero(2) |> Console.WriteLine 

雖然注意優先;當事情變得複雜時,您可能希望在lambda表達式周圍添加括號,即|> (fun m -> ...) |>

如果這種情況變成了很多,添加一些curried函數可以提供幫助。這適用於實例成員以大寫字母開頭的約定,而靜態成員或允許綁定函數以小寫字母開頭。這樣,如果你需要的管道很多,但也想支持點符號,你可以定義兩種類型的語法:

type MyClass2 (magicInt : int) = 
    member __.IsMagic i = i = magicInt 
    static member inline isMagic i (instance : MyClass2) = instance.IsMagic i 

現在,你可以在實例使用點符號,而且管道:|> MyClass2.isMagic 2 |> ...

isMagic的實現可能看起來過多,但重點是轉發到其他實現沒有額外的成本。這通常比複製實現要好,即使實現很短,因爲它不會創建額外的變體,可能會出現不同步,可能需要額外的測試等。

相關問題