Сквош кортежей из (a, (b, c)) в (a, b, c) в fsharp - PullRequest
0 голосов
/ 02 марта 2012

Имеет ли смысл определять такие функции

let squash12 (e:('a*('b*'c)   )) = e |> (fun (a,(b,c)  ) -> (a,b,c  ))
let squash21 (e:(('a*'b)*'c   )) = e |> (fun ((a,b),c  ) -> (a,b,c  ))
let squash13 (e:('a*('b*'c*'d))) = e |> (fun (a,(b,c,d)) -> (a,b,c,d))

let seqsquash12 (sa:seq<'T>) = sa |> Seq.map squash12
let seqsquash21 (sa:seq<'T>) = sa |> Seq.map squash21
let seqsquash13 (sa:seq<'T>) = sa |> Seq.map squash13

Я не смог найти другой способ сделать мой базовый код рекурсивным (приводя к вложенным кортежам), но выставил простую функцию, которая отображается в обобщенные n-мерные координаты.

Ответы [ 2 ]

2 голосов
/ 02 марта 2012

Я бы пометил ваши функции как встроенные, чтобы они могли просто быть

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

Кроме того, вам не нужны лямбды (fun ...)

2 голосов
/ 02 марта 2012

Да, имеет смысл сделать это.Предлагается избегать лямбда-выражений, чтобы упростить чтение этих функций:

let squash12 (a, (b, c)) = a, b, c

Если вы очень часто сталкиваетесь с внутренними кортежами с различной арностью, их преобразование в списки не является плохой идеей.Например, e становится кортежем из двух списков:

(a, (b, c)) ~> ([a], [b; c])
(a, b), c) ~> ([a; b], [c])
(a, (b, c, d)) ~> (a, [b; c; d])

И нам нужна только одна функция для последовательности:

let seqsquash sa = sa |> Seq.map (@)

Проблема в том, что вы теряете контроль над размеромвход.Сопоставление с образцом в списке может помочь:

let squash12 (xs, ys) = 
   match xs, ys with
   | [a], [b; c] -> xs, ys
   | _ -> failwith "Wrong input size"
...