我精通在F#中使用>>
和<<
运算符。然而,在查看F#源以建立更深入的理解后,我对此感到困惑:
let inline (>>) f g x = g(f x)
let inline (<<) f g x = f(g x)
如何从概念上解释这些表达?另外,你会如何形容这些表达?他们是否定义了一种类型?
答案 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问题以获取更多信息。