F# 具有成员函数的管道算子

F# 具有成员函数的管道算子,f#,F#,我可以将模块函数和静态成员函数与管道操作符一起使用。我可以将它与非静态成员函数一起使用吗 我的班级: type MyClass = class new() = {} member this.isZero(number: int): bool = number = 0 static member returnInt(): int = 33 end 使用静态成员: MyClass.r

我可以将模块函数和静态成员函数与管道操作符一起使用。我可以将它与非静态成员函数一起使用吗

我的班级:

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
使用非静态成员:

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#的清晰语法。

如果您已经有了实例的标识符,如问题中的
foo
foo.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
的实现可能看起来有些过分,但关键是要在不增加额外成本的情况下,继续使用其他实现。这通常比复制实现要好,即使实现很短,因为它不会创建可能会失去同步的额外变量,可能需要额外的测试等。

您试图实现什么,而“使用非静态成员”下的代码不会实现什么<代码>成员从未在实际成员声明之外的任何地方使用过。我认为OP正在尝试这样做:不,这是不可能的。在您的示例中,执行
foo.isZero(2)
有什么不对?