当前位置 : 主页 > 网络安全 > 测试自动化 >

F#:如何在不牺牲运行时性能的情况下为元组,三元组和四元组提供fst

来源:互联网 收集:自由互联 发布时间:2021-06-22
对于具有2个元素的基本元组,我们有fst和snd: let t2 = (2, 3)fst t2 // = 2snd t2 // = 3 简单.现在有3个元素 let t3 = (2, 3, 4) 我们如何访问第3个元素? msdn有一个答案(http://msdn.microsoft.com/en-us/libra
对于具有2个元素的基本元组,我们有fst和snd:

let t2 = (2, 3)
fst t2 // = 2
snd t2 // = 3

简单.现在有3个元素

let t3 = (2, 3, 4)

我们如何访问第3个元素? msdn有一个答案(http://msdn.microsoft.com/en-us/library/dd233200.aspx):

let third (_, _, c) = c

还很容易.但实际上是欺骗性的,因为我们不能在这样的三元组上使用fst和snd:

fst t3

error FS0001: Type mismatch. Expecting a int * int but given a int * int * int    
The tuples have differing lengths of 2 and 3

因此,具有挑战性的问题是:如何在不牺牲运行时性能的情况下为元组,三元组和四元组提供函数fst?

方法不起作用:

A)简单地添加fst(,, _)

let fst (a,_,_) = a // hides fst (a,b), so tuples dont work anymore

B)任何反射技巧,因为性能受到影响或棘手的功能组合导致在jitted代码级别的额外调用.

C)扩展方法(没有引导我任何地方,也许别人有更好的想法)

type Tuple<'T1, 'T2, 'T3> with
    member o.fst(a,b,c) = a
    static member fst(a,b,c) = a

除了有其他签名(t3.fst())我甚至无法使用Tuples扩展,尽管它们是类(不是结构).

d)

let fst = function 
          | (a,b) -> a
          | (a,b,c) -> a // FS0001: Type mismatch

这个问题意味着它的制定,而不是解决方法.实际上我相信答案是不可能提供在元组上运行的常用功能.

使用 this technique方法重载与内联函数相结合在运行时完全没有任何损失,因为重载解析发生在编译时,并且重载函数在调用站点处内联.

有更复杂的方法可以在库中组织这些通用元组函数,@ MaicicioScheffer已经发布了一些链接,显示了更多使用基本相同技术的实验.

这是一个非常短的独立代码片段,用于重载函数fst以使其与其他元组大小一起使用:

type Fst = Fst with
    static member ($) (Fst, (x1,_)) = x1
    static member ($) (Fst, (x1,_,_)) = x1
    static member ($) (Fst, (x1,_,_,_)) = x1
    // more overloads

let inline fst x = Fst $x
网友评论