Reputation: 37
While I understand that there may be transpose or ZipList functions in Haskell, I am trying to build my own transpose function that will take n lists of equal length m and transpose them into m lists of length n.
So far I have the function nearly working with the following code:
list = [[1,2,3],[4,5,6],[7,8,9]]
head' (x:xs) = x
head'' [] = []
head'' (xs:lxs) = head' xs:head'' lxs
tail' [] = []
tail' (x:xs) = xs
tail'' [] = []
tail'' (xs:lxs) = tail' xs:tail'' lxs
merge (xs:lxs) = (head' xs:head'' lxs):(merge (tail' xs:tail'' lxs))
and I get the following output when I run > merge list
in ghci I get:
[[1,4,7],[2,5,8],[3,6,9],[*** Exception: list2.hs:16:1-16: Non-exhaustive patterns in function head'
which I am pretty sure means that the base case of the empty list on my head'
function is missing. The list is transposed, just not closed. How do I deal with that problem in this case? I have an inkling that it might have to do with Maybe
, but I'm having trouble implementing it that way.
Upvotes: 1
Views: 204
Reputation: 532093
map
is all you need, in addition to the existing head
and tail
functions. For simplicity, this assumes that the input is always a non-empty list (i.e., xs
might be [[],[],[]]
, but never []
alone, so there's no problem with using head
or tail
.)
> map head list
[1,4,7]
> map tail list
[[2,3],[5,6],[8,9]]
> let foo xs = if null (head xs) then [] else map head xs : foo (map tail xs)
> foo list
[[1,4,7],[2,5,8],[3,6,9]]
Upvotes: 0
Reputation: 20544
You need to add exit conditions:
merge [] = []
merge ([]:xss) = merge xss
Upvotes: 1