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://docs.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/
答案 0 :(得分:9)
二元运算符的关联性仅在出现两次或多次相同的运算符时才有意义。当你有不同的运算符(这里:|>
和并列)时,重要的是它们的相对优先级。
并置的优先级高于|>
,因此
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)
即。 |>
的链表示函数组成 - 连续的管道步骤 - 而不是向函数传递更多的参数。
答案 1 :(得分:0)
默认情况下,函数是curry,你的原始表达式实际上是这样的:
c |> (SimpleFunction a b)
然后变为(SimpleFunction a b) c
。为此工作功能应用程序必须具有优先权。