Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# flatten nested tuples

Tags:

flatten

tuples

f#

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,

like image 743
Koenig Lear Avatar asked May 11 '17 15:05

Koenig Lear


1 Answers

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.

like image 76
Sean Avatar answered Sep 16 '22 11:09

Sean