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
.为此,功能应用程序必须具有优先权。