2012-03-02 11 views
0

では、このような機能を持ってしても意味がないに(、(B、C))からタプルを退治(a、b、c)は、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 - 実際には、タイプ推論が遅いとは思わない+このバージョンは実行時にはるかに高速になる(関数呼び出しを避ける) –

+0

@nicolas:一般的なケースの提案については私の答えを見てください。 – pad

2

はい、そうするのが理にかなっています。提案は読み、これらの機能を容易にするためにラムダを避けている:

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

あなたは非常に頻繁に多様アリティと内側のタプルが発生した場合は、リストに変換し、悪い考えではありません。

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

そして、我々は唯一のシーケンスのための機能を必要とする:例えば、e 2つのリストのタプルとなり

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

問題は、あなたが入力の大きさ以上のコントロールを失うです。リスト上のパターンマッチングを助けることができる:

let squash12 (xs, ys) = 
    match xs, ys with 
    | [a], [b; c] -> xs, ys 
    | _ -> failwith "Wrong input size" 
関連する問題