transpose
Real World Haskell, Exercise 4, p. 84:
Write a program that transposes the text in a file. For instance, it should convert “hello\nworld\n” to “hw\neo\nlr\nll\nod\n”.
cc :: String -> String -> String
cc x y = x ++ y ++ "\n"
transposeSingle :: String -> String
transposeSingle [] = []
transposeSingle (x:xs) = x : '\n' : (transposeSingle xs)
-- the accumulator string and the next line
transposeDouble :: String -> String -> String
transposeDouble x y = concat (zipWith (cc) (lines x) (lines (transposeSingle y)))
transposeEven :: [String] -> String
transposeEven [] = []
transposeEven [x] = (transposeSingle x)
transposeEven (x:xs) = foldl (transposeDouble) (transposeSingle x) xs
transpose :: String -> String
transpose s = transposeEven (pad (maxLength s) (lines s))
-- pad each line with spaces to maximum length
maxLength :: String -> Int
maxLength s = maximum (map length (lines s))
pad :: Int -> [String] -> [String]
pad _ [] = []
pad n (x:xs) = (padOneLine (n - (length x)) x) : (pad n xs)
padOneLine :: Int -> String -> String
padOneLine n s = if n > 0
then padOneLine (n-1) (s ++ ".")
else s
The exercise wasn’t clear on what you should do when not all lines were the same size, so I padded them out with periods.
This took way longer to implement than it should have, and I had to use several functions from later parts of the book. I certainly could have implemented this faster in Java or, to pick a language I haven’t been using day in and day out for 14 years, Python. Doubtless an experienced Haskell programmer could come up with a simpler implementation.
On the positive side, the interactive ghci shell was a big help in debugging this, and by their very nature Haskell’s pure functions are very amenable to testing and debugging in isolation. However, I still have to learn how to do real test driven development in Haskell. (One thing I proved to myself a couple of jobs ago was that TDD matters a lot more than what language you code in. I figured this out after I realized I could write correct Python code faster than the professional Python programmers we had hired because I was using TDD and they weren’t. This despite the fact that I knew next to no Python and they had years of experience in the language. Of course, an experienced Python programmer who did use test-driven development could still wipe the floor with me. )
January 19th, 2009 at 5:47 PM
You could try QuickCheck.
November 9th, 2009 at 9:01 PM
Isn’ the answer just
import Data.List
transposeWords :: String -> String
transposeWords s = foldr (\s -> \e -> s ++ “\n” ++ e ) “” (transpose (lines s))