FSharp函数参数的顺序

4

由于FSharp中具有多个参数的函数本质上被柯里化为仅具有一个参数的函数,因此Seq.filter的签名是否应该为

Seq.filter predicate source

它与当前有什么不同?

Seq.filter source predicate

谢谢


也许这应该是一个单独的问题。从性能角度来看,第一个比第二个更好吗? - Prasanna K Rao
我认为你是在暗示使用flip函数与第二个参数。其实你并不必须使用flip,只是无法更简洁地书写它。 - Guy Coder
好的,我明白了。谢谢。 - Prasanna K Rao
4个回答

10

第一个序列(谓词,顺序)更适合通过 |> 运算符链式组合序列组合器。通常情况下,您有一个单一的序列,对其应用多个操作/转换,考虑类似以下内容:

xs |> Seq.map ... |> Seq.filter ... |> Seq. ...

等等。如果将参数的顺序颠倒成(source,predicate),那么就会禁止这样做(或者至少使表达变得更加笨拙)。这也是为什么对于(几乎)所有默认的Seq组合器,操作所应用的序列都是最后一个参数的原因,可能还有部分应用。


6

它之所以如此

Seq.filter predicate source 

替换为

Seq.filter soure predicate 

这样你就可以做到这一点。

source
|> Seq.filter predicate

由于您更有可能使用Seq.filter predicate构建新功能

let isEven = Seq.filter (fun x -> x % 2 = 0)

现在你可以做到

source |> isEven

因为 F# 的历史渊源来自 OCaml,所以在某些函数中参数的顺序并不是像这样设定的。详情请参考:获取数组、列表或 Seq 中第 N 个元素的不同参数顺序


5

是的,Seq.filter接受一个谓词和一个待过滤的序列作为参数。如果你想要以相反的顺序提供它们,你可以编写一个函数来颠倒参数:

let flip f a b = f b a

那么你可以写代码:

然后你可以写

(flip Seq.filter) [1..10] (fun i -> i > 3)

现有的顺序更为便捷,因为它使得部分应用更加实用,例如:
 [1..3] |> Seq.map ((*)2) |> Seq.filter (fun i -> i > 2)

1
您还可以使用 ||> 管道符号来将具有两个参数签名的函数进行管道处理,或者对更广泛的签名部分应用 2 个参数。:)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接