Если вы проверите тип (++)
в ghci, вы получите:
Prelude> :t (++)
(++) :: [a] -> [a] -> [a]
Это означает, что вы можете добавлять списки только вместе (Помните, что String
является псевдонимом для [Char]
, так что этосписок).Тип hGetLine - Handle -> IO String
, а тип hGetLines
должен быть IO [String]
. Таким образом, вы не можете добавить эти значения.(:)
имеет тип a -> [a]
и работает лучше здесь.
if readable
then do
-- First you need to extract them
a <- hGetLine h
b <- hGetLines h
-- a and b have type String
-- Now we can cons them and then go back into IO
return (a : b)
То же самое относится к else []
.Вам необходимо вернуть значение типа IO [String]
.Измените его на return []
Кроме того, вы не сможете просто putStrLn
строк, поскольку (=<< hGetLines h)
дает вам [String]
, а не String
, что и ожидает putStrLn
.Это можно решить несколькими способами.Один из них состоит в том, чтобы сначала согласовать значения.putStrln . concat =<< (hGetLines h)
.Или вы можете напечатать каждую строку, используя mapM_ putStrLn (hGetLines h)
.