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

спасибо!

2 51

2 ответа:

тип 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

ответ Аймана имеет наибольший смысл для этой ситуации. В общем, если у вас [m ()] а ты хочешь m (), а затем использовать sequence_, где m может быть любая монада в том числе IO.