Распакуйте кортеж в другой кортеж

Предположим, мне нужно построить кортеж длины три:

(x , y, z)

И у меня есть функция, которая возвращает кортеж длины два - exampleFunction и два последних элемента создаваемого кортежа взяты из этого кортежа.

Как я могу сделать это без необходимости звонить exampleFunction два раза:

(x, fst exampleFunction , snd exampleFunction)

Я просто хочу сделать / достичь чего-то вроде

(x, exampleFunction)

но он жалуется, что кортежи имеют непревзойденную длину (конечно)

Не смотря на делать let y,z = exampleFunction()

4 ответа

Решение

Там может быть встроенная функция, но пользовательская будет работать так же хорошо.

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

Я не уверен, стоит ли отдельный ответ, но оба ответа, приведенные выше, не оптимальны, поскольку оба создают избыточность Tuple<'a, Tuple<'b, 'c>> при вызове вспомогательной функции. Я бы сказал, что пользовательский оператор будет лучше как для удобочитаемости, так и для производительности:

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

Проблема в том, что функция возвращает a*b поэтому тип возвращаемого значения становится 'a*('b*'c) который отличается от 'a*'b*'c лучшее решение - маленькая вспомогательная функция, такая как

let inline flatten (a,(b,c)) = a,b,c

тогда вы можете сделать

(x,examplefunction) |> flatten

У меня есть следующая функция в моем общем файле расширения. Вы можете найти это полезным.

   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
Другие вопросы по тегам