将元组解压缩到另一个元组中

时间:2012-03-21 23:37:45

标签: f# tuples iterable-unpacking

假设我需要构造一个长度为3的元组:

(x , y, z)

我有一个函数返回一个长度为2的元组 - exampleFunction,并且要构造的元组的最后两个元素来自这个元组。

如何在不必拨打exampleFunction两次的情况下执行此操作:

(x, fst exampleFunction , snd exampleFunction)

我只是想做/像

这样的事情
(x, exampleFunction)

但它抱怨元组有无与伦比的长度(当然)

不看let y,z = exampleFunction()

4 个答案:

答案 0 :(得分:3)

可能有内置功能,但自定义功能也可以。

let repack (a,(b,c)) = (a,b,c)
repack (x,exampleFunction)

答案 1 :(得分:2)

我不确定它是否值得单独回答,但上面提供的两个答案都不是最优的,因为在调用辅助函数时都构造冗余Tuple<'a, Tuple<'b, 'c>>。我会说自定义运算符对于可读性和性能都会更好:

let inline ( +@ ) a (b,c) = a, b, c
let result = x +@ yz // result is ('x, 'y, 'z)

答案 2 :(得分:1)

你遇到的问题是函数返回a*b所以返回类型变为'a*('b*'c),这与'a*'b*'c不同,最好的解决方案是像

这样的小辅助函数
let inline flatten (a,(b,c)) = a,b,c

然后你可以做

(x,examplefunction) |> flatten

答案 3 :(得分:0)

我的公共扩展文件中有以下功能。 您可能会觉得这很有用。

   let inline squash12 ((a,(b,c)  ):('a*('b*'c)   )):('a*'b*'c   ) = (a,b,c  )
   let inline squash21 (((a,b),c  ):(('a*'b)*'c   )):('a*'b*'c   ) = (a,b,c  )
   let inline squash13 ((a,(b,c,d)):('a*('b*'c*'d))):('a*'b*'c*'d) = (a,b,c,d)

   let seqsquash12 (sa:seq<'a*('b*'c)   >) = sa |> Seq.map squash12
   let seqsquash21 (sa:seq<('a*'b)*'c   >) = sa |> Seq.map squash21
   let seqsquash13 (sa:seq<'a*('b*'c*'d)>) = sa |> Seq.map squash13

   let arrsquash12 (sa:('a*('b*'c)   ) array) = sa |> Array.map squash12
   let arrsquash21 (sa:(('a*'b)*'c   ) array) = sa |> Array.map squash21
   let arrsquash13 (sa:('a*('b*'c*'d)) array) = sa |> Array.map squash13