Vzqivan
Vzqivan

Reputation: 401

Something wrong with a Haskell List

I do not know what happened with this. I have a list L = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

and i need a function that gives me this: L = [[1, 4, 7],[2, 5, 8],[3, 6, 9]]

until now i have this:

rotar2 [ ] = [ ]
rotar2 l = [map head l] ++ rotar2(map tail l)

and it works but not at all.. it sends me this error:

[[1,4,7],[2,5,8],[3,6,9],[ Program error: pattern match failure: head []

what should i do?

Upvotes: 0

Views: 127

Answers (2)

Stefan Holdermans
Stefan Holdermans

Reputation: 8050

You are repeatedly taking the heads and tails of every list in your function's input. Eventually, one of these lists will only have the empty list left as a tail and attempting to take the head of that empty list will then fail.

  rotar2 [[1,2,3],[4,5,6],[7,8,9]]
    = [[1,4,7]] ++ rotar2 [[2,3], [5,6], [8,9]]
    = [[1,4,7]] ++ [[2,5,8]] ++ rotar2 [[3], [6], [9]]
    = [[1,4,7]] ++ [[2,5,8]] ++ [[3,6,9]] ++ rotar2 [[],[],[]]
    = [[1,4,7]] ++ [[2,5,8]] ++ [[3,6,9]] ++ [head [],head[],head []] ++ ...
    = [[1,4,7],[2,5,8],[3,6,9],[⊥,⊥,⊥],...]

Transpose

The function rotar2 that you are trying to define is usually called transpose and can be implemented rather straightforwardly as

transpose :: [[a]] -> [[a]]
transpose []         = repeat []
transpose (xs : xss) = zipWith (:) xs (transpose xss)

The idea is that a nonempty list of lists, say [[1,2,3],[4,5,6],[7,8,9]], can be transposed inductively by first transposing its tail [[4,5,6],[7,8,9]], yielding [[4,7],[5,8],[6,9]], and then prepending the elements of the head list [1,2,3] to the elements of the transposed tail:

[ 1 : [4,7] , 2 : [5,8] , 3 : [6,9] ]

Hence:

> transpose [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[1,4,7],[2,5,8],[3,6,9]]

In the standard libraries, this function is exported by the module Data.List.

Upvotes: 4

effectfully
effectfully

Reputation: 12725

You can redefine the transpose function in one line:

transpose = getZipList . traverse ZipList

All the definitions and instances are in the Control.Applicative and Data.Traversable modules. It's the same definition as in the Stefan Holdermans answer modulo typeclasses and wrapping-unwrapping stuff.

Upvotes: 0

Related Questions