Вы находитесь в монаде IO
, поэтому каждая строка должна выдавать IO a
, но ваше понимание списка дает ... ну, список [a]
. К счастью, есть функция sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
, которая превратит ваш [IO ()]
в один IO ()
, одновременно выполняя в нем все действия ввода-вывода. Таким образом, ваш else
блок должен выглядеть следующим образом:
else do files <- getDirectoryContents filePath
sequence_ [countLines(file) | file <- files]
pure 0
Как упоминает Виллем, можно упростить их еще больше, используя mapM_ :: (Foldable f, Monad m) => (a -> m b) -> f a -> m ()
:
else do files <- getDirectoryContents filePath
mapM_ countLines files
pure 0