Squashing tuples from (a,(b,c)) to (a,b,c) in fsharp
-
29-11-2019 - |
Question
Does it make sense to have such functions defined
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
I could not find another way to make my core code recursive (leading to nested tuples), yet expose simple function that maps to generalized n-dimensional coordinates.
Solution
I would have marked your functions as inline so that they could just be
let inline squash1 (a,(b,c)) = (a,b,c)
Also, you don't need the lambdas (fun ...)
OTHER TIPS
Yes, it makes sense to do so. The suggestion is avoiding lambda to make these functions easier to read:
let squash12 (a, (b, c)) = a, b, c
If you encounter inner tuples with varied arity very often, converting them into lists is not a bad idea. For example, e
becomes a tuple of two lists:
(a, (b, c)) ~> ([a], [b; c])
(a, b), c) ~> ([a; b], [c])
(a, (b, c, d)) ~> (a, [b; c; d])
And we only need one function for sequence:
let seqsquash sa = sa |> Seq.map (@)
The problem is you lose the control over size of input. Pattern matching on list could help:
let squash12 (xs, ys) =
match xs, ys with
| [a], [b; c] -> xs, ys
| _ -> failwith "Wrong input size"