Подтвердить что ты не робот

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 )). Но было бы гораздо проще использовать карту...

Спасибо!

4b9b3361

Ответ 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.