2012-03-02 4 views
0

ли смысл иметь такие функции, определенныедавя кортежи (а, (б, в)) (а, б, в) в FSharp

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

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

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

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

+0

Thks. Я заметил, что вывод типа медленный (я использую материал более высокого порядка только для базовых функций), поэтому я мог бы также указать тип, если он ускорит его. – nicolas

+0

@nicolas - действительно, я не думаю, что тип inferrence медленный + эта версия будет намного быстрее во время выполнения (избегает вызова функции) –

+0

@nicolas: см. Мой ответ на предложение в общих случаях. – pad

2

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

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" 
Смежные вопросы