You can create a function like this using more general functions like map
, fst
, snd
and splitAt
, all of which are in Prelude.
primeiros :: [[a]] -> [[a]]
primeiros xs = helper1 ([], xs)
helper1 :: ([[a]],[[a]]) -> [[a]]
helper1 (hs, []) = hs
helper1 (hs, ls) = helper1 ((f2 . f1 $ ls) : hs, checaNull (f3 . f1 $ ls))
where f1 y = map (splitAt 1) y
f2 y = concat $ map fst y
f3 y = map snd y
checaNull [] = []
checaNull ls@(x:xs) = if not (null x) then ls else checaNull xs
This is a simple but very inefficient implementation. It is inefficient because
- Each time
helper1
is called, the list is traversed twice: once in f2 . f1 $ ls
and another in f3 . f1 $ ls
.
- The higher the input list, the longer the time consumed by
f2
due to concat
.
The result also comes out slightly different. I changed the example to show the difference:
*Main> lista = [[1,10,100,1000],[2,20,200,2000,2],[3,30,300,3000],[4,40,400,4000,4]]
*Main> primeiros lista
[[2,4],[1000,2000,3000,4000],[100,200,300,400],[10,20,30,40],[1,2,3,4]]
If you want to invert the output order, simply type helper1 (hs, []) = reverse hs
as the first default of helper1
, which increases the processing time because you will need to scroll through the entire output list.