2017-05-11 13 views
5

明示的にマッピングせずにF#の任意のサイズのタプルをフラット化する方法はありますか?F#はネストされたタプルをフラットにします

(fun ((((a0,a1),a2),b),c) -> (a0,a1,a2,b,c)) 

メモ:私はFParsecからこのような種類のタプルを取得していますが、一般的に利用可能な場合は機能が便利です。

おかげで、

+4

FParsecでは、 'tuple3、tuple4、tuple5'または' pipe3、pipe4、pipe5'関数を使用して、より多くのパーサーを組み合わせることができます。 – TheInnerLight

+0

@TheInnerLight素晴らしい点ありがとう –

答えて

3

あなたは簡単にそれを行うことはできませんが、反射のビットでそれが可能である:

let isTuple tuple = 
    Microsoft.FSharp.Reflection.FSharpType.IsTuple(tuple.GetType()) 

let tupleValues (tuple : obj) = 
    Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields tuple |> Array.toList 

let rec flatten tupleFields = 
    tupleFields |> List.collect(fun value -> 
     match isTuple value with 
     | true -> flatten (tupleValues value) 
     | false -> [value] 
    ) 

let tupleToList (tuple : obj) = 
    if isTuple tuple 
     then Some (tupleValues tuple |> flatten) 
     else None 

したがって、たとえば:

let s = tupleToList ((100,101,102,103),1,2,3,(4,5)) 

はあなたを与えるだろう:

[100; 101; 102; 103; 1; 2; 3; 4; 5] 

注:これはerはコードが見つかったhereに基づいています。

+1

反射は絶対的な最後の手段であるべきです。型の安全性と性能に関しては一般的にはひどいです。 @TheInnerLightが言ったことをむしろやって、FParsecの専用機能を使っています。 – Tarmil

+1

@タルミールあなたはTarmillに完全に同意しました - ちょうど私がSeanの答えが正しい質問を表現する方法を与えました。 –

関連する問題