繁体   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