File manipulation with Haskell I am trying to pick up Haskell!

But I feel like my code is a bit painful to write and read.

Do you have any pointers on how to improve its readability / style?

main = do
    contents &lt;- fmap tail . fmap lines . readFile $ "testInput"
    let input = map pair_to_tuple .(map (map read)) . map words $ contents :: [(Int,Int)]
    let result = map (uncurry waffles) $ input
    let decorated_result = ["Case #" ++ show i ++ ": " ++ show s | (i,s) &lt;- zip [1..length result] result] 
    writeFile "output.txt" $ unlines $ decorated_result

waffles row col = (row - 1)*(col - 1)

pair_to_tuple [a,b] = (a,b)


This script reads a file whose first line is a title, then every line is a couple of numbers. Then it drops the first line, and processes every pair of numbers using the function waffles, then it writes it back to an output file.
contents &lt;- fmap tail . fmap lines . readFile $ "testInput"


can be written as

contents &lt;- (tail . lines) &lt;$&gt; readFile "testInput"


Here we take advantage of the law fmap f . fmap g == fmap (f . g). &lt;$&gt; is an infix version of fmap. $ is extraneous here.



let input = map pair_to_tuple .(map (map read)) . map words $ contents :: [(Int,Int)]


can be written as

let input = map (pair_to_tuple . (map read) . words) contents :: [(Int,Int)]


For lists map = fmap, so map f . map g == map (f . g) also holds.



In

let result = map (uncurry waffles) $ input


the $ sign is also extraneous.



let decorated_result = ["Case #" ++ show i ++ ": " ++ show s | (i,s) &lt;- zip [1..length result] result]


You can exploit Haskell's lazy evaluation and create infinite list to zip with:

let decorated_result = ["Case #" ++ show i ++ ": " ++ show s | (i,s) &lt;- zip [1..] result]




Otherwise I'd say the code is fine.