Haskell: нельзя использовать "map putStrLn"?
У меня есть список строк и пробовал это:
ls = [ "banana", "mango", "orange" ]
main = do
map PutStrLn list_of_strings
Это не сработало, и я не понимаю, почему.
ghc print-list.hs
print-list.hs:3:0:
Couldn't match expected type `IO t' against inferred type `[IO ()]'
In the expression: main
When checking the type of the function `main'
Любые подсказки? Я полагаю, что это связано с отображением карты, а не значением, но я не нашел простой способ исправить это.
В настоящее время единственным способом, которым я знаю, чтобы напечатать список строк, является запись функции, которая будет перебирать список, печатать каждый элемент (печатать, если список [a], но печатать и рекурсировать, если он (a: b )). Но было бы гораздо проще использовать карту...
Спасибо!
Ответы
Ответ 1
Тип функции main
должен быть IO t
(где t
- переменная типа). Тип map putStrLn ls
- [IO ()]
. Вот почему вы получаете это сообщение об ошибке. Вы можете убедиться в этом, выполнив следующее в ghci
:
Prelude> :type map putStrLn ls
map putStrLn ls :: [IO ()]
Одним из решений проблемы является mapM
, которая является "монадической" версией map
. Или вы можете использовать mapM_
, что совпадает с mapM
, но не собирает возвращаемые значения из функции. Поскольку вам не нужно возвращать значение putStrLn
, более целесообразно использовать mapM_
здесь. mapM_
имеет следующий тип:
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
Вот как это использовать:
ls = [ "banana", "mango", "orange" ]
main = mapM_ putStrLn ls
Ответ 2
Ответ Аймана имеет смысл для этой ситуации. В общем случае, если у вас есть [m ()]
и вы хотите m ()
, используйте sequence_
, где m
может быть любой монадой, включая IO
.