Is it possible to convert a list of tuples [(Int,Int)]
as a generic way which valid to any input size ? .. i saw in various questions thats its not possible gen
This can be also achieved by the homogeneous tuples library (disclaimer: which I'm the author of). It defines wrappers for tuples that make them instances of Traversable
(and others such as Applicative
and Monad
). So a tuple can be converted to a list by toList . Tuple2
(where toList is from Data.Foldable
) and
f :: [(a, a)] -> [a]
f = concatMap (toList . Tuple2)
You can also use it for other tuples, for example concatMap (toList . Tuple5)
etc.
Your question is not very certain about how the tuples should be converted into a list. I assume that you want to have them flattend - for instance, [(1,2),(3,4)]
should become [1,2,3,4]
.
This translation is only possible, if the two elements of your tuple are of the same type. In this case you can do something like this:
tupleToList :: [(a,a)] -> [a]
tupleToList ((a,b):xs) = a : b : tupleToList xs
tupleToList _ = []
In the general case, such a translation is impossible. One thing I could imagine to make the impossible possible is to use Either
to wrap up the two different types:
tupleToList :: [(a,b)] -> [Either a b]
tupleToList ((a,b):xs) = Left a : Right b : tupleToList xs
You could also use a fold and avoid explicit recursion:
tupleToList = foldr (\(f,s) a -> f : s : a) []
Or:
tupleToList = foldl (\a (f,s) -> a ++ [f,s]) []
(For elements of the same type)
f [] = []
f [(x, y) : xs] = x : y : f xs
The lens library handles this and similar cases consistently.
> import Control.Lens
> toListOf (traverse . both) [(1,2),(3,4)]
^ ^
| |> Traversal of the tuple (a, a)
|> Traversal of a list [b]
[1,2,3,4]
To convert from a list of lists:
> toListOf (traverse . traverse) [[1,2],[3,4],[5,6,7]]
[1,2,3,4,5,6,7]
addition edit:
traverse
works with Traversabletraverse
will work with any datatype that has a Traversable
instance, for example trees.
> import Data.Tree
> let t = Node 1 [Node 2 [Node 3 [], Node 4 []], Node 5 []]
> let prettyTree = drawTree . fmap show
> prettyTree t
1
|
+- 2
| |
| +- 3
| |
| `- 4
|
`- 5
> toListOf (traverse . traverse) [t, t]
[1,2,3,4,5,1,2,3,4,5]