理解F#组合运算符

时间:2013-07-31 22:54:30

标签: f# pointfree function-composition

我精通在F#中使用>><<运算符。然而,在查看F#源以建立更深入的理解后,我对此感到困惑:

let inline (>>) f g x = g(f x)
let inline (<<) f g x = f(g x)

如何从概念上解释这些表达?另外,你会如何形容这些表达?他们是否定义了一种类型?

2 个答案:

答案 0 :(得分:5)

我认为描述它的最佳方式是一个例子,因为查看定义可能会有点混乱。假设你有这个:

let isEven x = x % 2 = 0
[1 .. 99] |> List.filter (fun x -> not (isEven x))

使用合成运算符,您可以将其重写为其中之一:

[1 .. 99] |> List.filter (isEven >> not)
[1 .. 99] |> List.filter (not << isEven)

更一般地说,如果您有这样的事情:

data |> a |> b |> c

您可以这样重写:

data |> (a >> b >> c)

并将a >> b >> c解释为执行a,然后执行b,然后执行c 。如果您更喜欢更传统的向后排序:

(a (b (c data)))

您可以将其重写为

((a << b << c) data)

这也称为自由点风格。在正常情况下,它可能比使用普通样式更难阅读,但是当传递到更高阶函数时,它可以更容易阅读,因为您不必添加(fun x -> )噪音。

答案 1 :(得分:2)

正如msdn page for F# functions所说,“F#中的函数可以由其他函数组成。函数function1和function2的两个函数的组合是另一个函数,它代表函数1的应用程序跟随函数2的应用。”

可以认为它与管道运算符类似,只是没有指定最后/最深的参数;例如以下两行是等效的:

let composed = f >> g
let piped x = g <| f x

另请参阅this问题以获取更多信息。