相关性,优先级和F#管道向前

时间:2017-11-13 07:59:45

标签: 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://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/

What is associativity of operators and why is it important?

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

2 个答案:

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