[英]How do I use map over a list with do notation - ie avoid type `IO ()' with type `[IO ()]'?
所以這個問題更多地是關於Monads(尤其是Fay),但是我的例子使用了IO monad。
我有一個函數,其中輸入是一個字符串列表,我想逐個打印每個字符串。 所以這是我的想法:
funct :: [String] -> ?
funct strs = do
map putStrLn strs
但是不起作用,因為它返回一個類型[IO()]。 所以我的問題是,我將如何映射列表,並將其視為我在逐行執行函數,以典型的符號,迭代風格(如下所示)?
funct :: [String] -> IO ()
funct strs = do
putStrLn (strs !! 0)
putStrLn (strs !! 1)
...
大多數標准庫列表函數都有以M
結尾的monadic版本:
map :: (a -> b) -> [a] -> [b]
mapM :: (Monad m) => (a -> m b) -> [a] -> m [b]
replicate :: Int -> a -> [a]
replicateM :: (Monad m) => Int -> m a -> m [a]
有時它們在Prelude
,有時它們在Control.Monad
。 我建議使用hoogle來查找它們。
特別針對您的情況,我經常使用mapM_ putStrLn
。
使用順序
sequence $ map putStrLn strings
sequence將monad從monad列表中拉出來
sequence :: Monad m => [m a] -> m [a]
從而將(將putStrLn字符串):: [IO a]轉換為IO [a]。 您可能希望使用相關的sequence_來刪除返回值。
你也可以使用forM_:: Monad m => [a] -> (a -> mb) -> m ()
(通常看起來更好,但對我來說有一點迫切的感覺)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.