为什么使用反向管道运算符而不是函数链?
let distanceFromOrigin aPoint =
let square x = x * x
sqrt (square aPoint.x + square aPoint.y)
VS
let distanceFromOrigin aPoint =
let square x = x * x
sqrt <| square aPoint.x + square aPoint.y
答案 0 :(得分:33)
由于左侧关联性(f <| g <| x
被解析为(f <| g) <| x
而遗憾地不被f <| (g <| x)
等同于x |> g |> f
),我发现它仅在您需要时才有用要删除括号(而不是f (long expression)
,请编写f <| long expression
)。
答案 1 :(得分:20)
在f x
,x |> f
和f <| x
之间进行选择主要是一个问题
样式。选择一个而不是选择一个没有绝对的规则
其他。 |>
运算符非常受欢迎,使用它是个好主意。
<|
不太常见,但如果你查看编译器的来源,你会发现几个
使用。例如:
raise <| System.InvalidOperationException (SR.GetString(SR.QillFormedAppOrLet))
if info.precision then
failwithf "%s" <| FSComp.SR.forFormatDoesntSupportPrecision(ch.ToString())
<|
用于删除括号,我认为它会生成代码
仔细使用时更具可读性。当你看到它时,你就知道了
以下表达式是函数的参数。你没有
必须搜索右括号。我建议你谨慎使用它,你通常应该避免在同一个表达式中混合<|
和|>
,因为它可能非常
混乱。
我有时喜欢使用此运算符来创建“块”
fun
或lazy
关键字。
let f (l: Lazy<_>) = ()
let g (f: _ -> _ -> _) = ()
f <| lazy
let x = 1 + 1
x * x
g <| fun x y ->
let sqr n = n * n
sqr x + sqr y
该块基于缩进,因此它非常适合F#代码。谢谢
到<|
运算符,您不需要尾随括号。
答案 2 :(得分:6)
正如Scott Wlaschin所指出的那样here,如果你需要将数据作为第一个参数(而不是最后一个)传递到管道链的某个地方,则后向管道运算符很有用 。请考虑以下事项:
let replace (replaceThis: string) (withThis: string) (input: string) =
input.Replace(replaceThis, withThis)
let joinWith (input1: string) (input2: string) =
input1 + " " + input2
let testString = "Happy"
let amendedString = testString
|> replace "H" "Cr"
|> joinWith "birthday"
amendedString
是“生日蹩脚”。让我们说我想让它成为“蹩脚的生日”。我可以通过使用反向管道运算符来实现这一点:
let amendedString = testString
|> replace "H" "Cr"
|> joinWith <| "birthday"
现在amendedString
是“生日快乐”,这就是我想要的。