簡體   English   中英

如何在帶有符號的列表上使用映射 - 即避免使用類型“[IO()]”鍵入`IO()'?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM