Is there some way to convert between F# List and F# Tuple?
For example:
[1;2;3] -> (1,2,3)
(1,2,3,4) -> [1;2;3;4]
I need two Functions to do that:
let listToTuple list = ...
let tupleToList tuple = ...
Thank you in advance.
Is there some way to convert between F# List and F# Tuple?
For example:
[1;2;3] -> (1,2,3)
(1,2,3,4) -> [1;2;3;4]
I need two Functions to do that:
let listToTuple list = ...
let tupleToList tuple = ...
Thank you in advance.
Besides listToTuple then pblasucci has the right answer. But you wont be happy with the result unless you know something about type types involved, or if you wan't to do a lot of boxing and unboxing.
Making use of the PropertyInfo structure one can build a list recursively. A problem with this approach is that the type information is lost and the result is produced as a list of obj. Nevertheless, this does solve the tuple to list portion of the question.
As already pointed out, this is a tricky problem, because tuple isn't a single type - it is a family of types such as
int * int * int
orint * int
and F# doesn't provide any way for taking the whole family of types as an argument. You can either write many similar functions (which is very uncomfortable) or use reflection (which is a bit slow and isn't type-safe).Alternatively, you could limit the function to tuples with some structure - for example, instead of working with
(1, 2, 3, 4)
, you could use nested tuples like(1, (2, (3, 4)))
. This is a bit less comfortable, but it keeps the type safety and it isn't as bad.Then you can easily write combinators for constructing conversion functions on the fly:
Then you can combine functions
tl
andte
to create a type-safe function that converts nested tuple containing 4 elements to a list like this:Similarly, you can create functions for converting list to tuples - note that this may throw an exception if the list doesn't match the expected format:
I guess this is probably as close to typesafe and reusable function for converting between tuples and lists as it can get. It isn't perfect (at all), but that's caused by the fact that you're trying to implement a very rarely used operation. In F#, the distinction between tuples and lists is clearer than for example in Python (which is dynamic, so it doesn't have to deal with static type safety).
Actually you need
2*n
functions wheren
is the greatest tuple size you want to support. A tuple containing three ints has a completely different type than a tuple containing four ints, so you need to write a tupleToList and a listToTuple function for each one separately.Also note that you for listToTuple you need to know the size of the tuple you want to get at compile-time. I.e. you can't create a function that decides whether to return
(int, int, int)
or(int, int)
depending on the length of the input list (since as I said, they're totally different types). You'd have to have a functionlistToNTuple
that takes a list of at least N elements and returns a N-tuple.It might be possible to write size-independent functions for this by using reflection, but since you couldn't know the type of any tuple returned by such a function at compile-time, it'd be quite painful to use.
Well, it ain't pretty but:
I'm not sure how you'd go back the other way though. And I'm really not sure this would be sensible, but if you really have to.