关联性、优先级和 F# 管道转发



F# 管道前向可以表示为:

let (|>) x f = f x

例如:

let SimpleFunction (a : typeA) (b : typeB) (c : typeC)=
    printf "OK."
// No problem here.
SimpleFunction a b c
// Using pipe-forward
c |> SimpleFunction a b
// No problem here. Interpreted as the same as above.

但是,根据文档,管道前向运算符是左关联的。

https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/symbol-and-operator-reference/

所以,我期待管道前锋语句:

// Original Expression
c |> SimpleFunction a b
// to be equivalent to:
(c |> SimpleFunction) a b
// Which is equivalent to:
SimpleFunction c a b
// Error!! SimpleFunction takes typeA, then typeB, then typeC.

为什么编译器不将管道前向表达式"解释"为错误表达式?我对运算符优先级/关联性有任何困惑吗?


其他来源:

http://theburningmonk.com/2011/09/fsharp-pipe-forward-and-pipe-backward/

什么是运算符的关联性,为什么它很重要?

https://en.wikipedia.org/wiki/Operator_associativity

仅当

同一运算符出现两次或多次时,二元运算符的关联性才重要。当您有不同的运算符(此处:|> 和并列(时,重要的是它们的相对优先级。

并列的优先级高于|>,因此

c |> SimpleFunction a b

解析为

(c) |> (SimpleFunction a b)

所以,根据|>的定义,它相当于

(SimpleFunction a b) (c)

通常会写

SimpleFunction a b c

最后一个等价是由于并列是左关联。

|>是左关联的这一事实意味着像这样的表达式

x |> f |> g

解析为

(x |> f) |> g

相当于

g (f x)

|>链表达函数组合 - 连续的管道步骤 - 而不是向函数传递更多参数。

函数默认是柯里化的,你原来的表达式其实是这样的:

c |> (SimpleFunction a b)然后变成(SimpleFunction a b) c.为此,功能应用程序必须具有优先权。