It is possible to create such a function using more general functions such as map
, fst
, snd
and splitAt
, all continas 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 rather inefficient implementation. It is inefficient because
- every time
helper1
is called, the list is crossed twice: once in f2 . f1 $ ls
and another in f3 . f1 $ ls
.
- the longer the entry list, the longer the time consumed by
f2
due to concat
.
The result also comes out a little 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 reverse the output order, just write helper1 (hs, []) = reverse hs
as the first standard of helper1
, which increases the processing time because you will need to go through the entire output list.