Вопрос

У меня есть список строк, и я попробовал это:

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

Спасибо!

Это было полезно?

Решение

Тип 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top