明示的にマッピングせずにF#の任意のサイズのタプルをフラット化する方法はありますか?F#はネストされたタプルをフラットにします
(fun ((((a0,a1),a2),b),c) -> (a0,a1,a2,b,c))
メモ:私はFParsecからこのような種類のタプルを取得していますが、一般的に利用可能な場合は機能が便利です。
おかげで、
明示的にマッピングせずにF#の任意のサイズのタプルをフラット化する方法はありますか?F#はネストされたタプルをフラットにします
(fun ((((a0,a1),a2),b),c) -> (a0,a1,a2,b,c))
メモ:私はFParsecからこのような種類のタプルを取得していますが、一般的に利用可能な場合は機能が便利です。
おかげで、
あなたは簡単にそれを行うことはできませんが、反射のビットでそれが可能である:
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に基づいています。
反射は絶対的な最後の手段であるべきです。型の安全性と性能に関しては一般的にはひどいです。 @TheInnerLightが言ったことをむしろやって、FParsecの専用機能を使っています。 – Tarmil
@タルミールあなたはTarmillに完全に同意しました - ちょうど私がSeanの答えが正しい質問を表現する方法を与えました。 –
FParsecでは、 'tuple3、tuple4、tuple5'または' pipe3、pipe4、pipe5'関数を使用して、より多くのパーサーを組み合わせることができます。 – TheInnerLight
@TheInnerLight素晴らしい点ありがとう –