在获取Array,List或Seq的第N个元素的函数中有不同的参数顺序是否有充分的理由:
Array.get source index
List .nth source index
Seq .nth index source
我想使用管道运算符,似乎只能使用Seq:
s |> Seq.nth n
有没有办法在Array或List中使用相同的表示法?
答案 0 :(得分:15)
我认为没有任何理由以这种方式定义Array.get
和List.nth
。鉴于在F#中管道输出很常见,它们应该被定义,以便source
参数最后出现。
如果是List.nth
,它的变化不大,因为您可以使用Seq.nth
,时间复杂度仍为O(n)
,其中n
是列表的长度:< / p>
[1..100] |> Seq.nth 10
在数组上使用Seq.nth
不是一个好主意,因为您丢失了随机访问权限。要保持O(1)
的{{1}}运行时间,您可以定义:
Array.get
通常,使用[<RequireQualifiedAccess>]
module Array =
/// Get n-th element of an array in O(1) running time
let inline nth index source = Array.get source index
函数可以缓解不同的参数顺序:
flip
您可以直接在上述功能中使用它:
let inline flip f x y = f y x
答案 1 :(得分:7)
只需使用反向管道运算符:
[1..1000] |> List.nth <| 42
由于两个运算符都是关联的,x |> f <| y
被解析为(x |> f) <| y
,这就行了。
后向管道运算符也很有用:f (very long expression)
可以替换为f <| very long expression
。
答案 2 :(得分:5)
由于Pad和bytebuster回答了你的上一个问题,我将重点关注原因。
这是基于我目前的知识,而不是历史事实。
由于来自OCaml和OCaml的F#具有Array和List但not Seq而F#使用|&gt;对于自然流水线操作以及type checking和OCaml lacks the pipleline operator,F#的作者为Seq做了切换。但显然要与OCaml向后兼容,他们并没有切换所有内容。