Koenig Lear
Koenig Lear

Reputation: 2436

F# flatten nested tuples

is there a way to flatten tuples of arbitrary size in F# without explicitly mapping them?

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

As a note I'm getting these kind of tuples from FParsec but the capability would be convenient if it was available generally.

thanks,

Upvotes: 8

Views: 1181

Answers (1)

Sean
Sean

Reputation: 62532

You can't do it easily, but with a bit of reflection it is possible:

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

So, for example:

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

Will give you:

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

NOTE: This answer is based on code found here.

Upvotes: 4

Related Questions