Как мы печатаем вывод функции, возвращающей строку IO в stdout? Я не могу использовать показ или печать.
Запись строки ввода-вывода в stdout в Haskell
Ответ 1
Если вы хотите напечатать результат функции foo :: Int -> IO String
(например), вы можете сделать
main = do
str <- foo 12
putStrLn str
или, без примечаний,
main = foo 12 >>= putStrLn.
Обозначение do - это синтаксический сахар для второго, в котором используется основной комбинатор (>>=)
, который имеет тип
(>>=) :: Monad m => m a -> (a -> m b) -> m b
IO
является экземпляром класса Monad
, поэтому вы можете использовать его здесь.
foo :: Int -> IO String
foo 12 :: IO String
putStrLn :: String -> IO ()
(foo 12) >>= putStrLn :: IO ()
Ответ 2
Как мы печатаем вывод функции, которая возвращает строку IO в stdout?
Хорошо, посмотрим. Здесь функция, которая возвращает строку IO:
dumbFunction :: a -> IO String
dumbFunction x = getLine
dumbFunction
является немой функцией (но тем не менее функцией!). Он игнорирует свой вход, а затем возвращает getLine
, который имеет тип IO String
.
Итак, скажите мне, как вы печатаете getLine :: IO String
? Ответ в том, что нет! Это то, что мы называем "действием IO". Обратите внимание, что действие IO не является функцией, потому что оно не принимает ввода. (Тем не менее, операции ввода-вывода могут получать входные данные, а также операции ввода-вывода, такие как чтение stdin, как это делает getLine
. Но он не считается "функцией", потому что он не принимает никакого традиционного ввода)
Поэтому вместо того, чтобы распечатывать действие, вы, вероятно, захотите запустить действие, а затем распечатать результат. Это можно сделать, как описал Даниэль Фишер (с <-
, который можно рассматривать как оператор "run" ).