Any function which calls an IO function must itself by an IO function. So this is Incorrect:
numLinesList' :: [String] -> [Int]
numLinesList' (firstFile:rest)
= (numLines firstFile):(numLinesList' rest)Correct:
numLinesList :: [Filename] -> IO [Int]
numLinesList (firstFile:rest)
= do firstLen <- numLines firstFile
restLen <- numLinesList rest
return $ firstLen : restLenWalk through the transformation...