如何将字符串列表传递给putStr

时间:2014-04-17 16:50:42

标签: haskell monads

如何使用putStr和map输出字符串列表?我想做点什么:

s=["test1","test2"]
map putStr s

但是对monad没有经验,也不知道如何正确...

非常欢迎任何形式的提示!

2 个答案:

答案 0 :(得分:7)

这里正确的做法是使用mapM_ :: Monad m => (a -> m b) -> [a] -> m ()。但是,如果您想了解一些有用的Prelude函数......

我们这里有两个功能,

map :: (a -> b) -> [a] -> [b]
putStr :: String -> IO ()

如果我们将putStr的类型替换为map(即。a ~ Stringb ~ IO ()),我们就会

map putStr :: [String] -> [IO ()]

所以这需要一个字符串列表,并给我们一个IO ()个动作列表; IO计算不会返回任何有用的内容。

我们希望将[IO ()]转换为IO (...),因为我们需要IO作为最外层才能在main :: IO () <中使用它/ p>

sequence :: Monad m => [m a] -> m [a]中的Prelude函数正是我们所需要的。它需要一个monadic动作列表,执行它们并将结果返回到monad中包含的列表中。直观地,它将monad移动到最外层。

sequence . map putStr :: [String] -> IO [()]

这是非常接近的,但我们仍然有IO [()]而不是IO (),我们并不真正关心[()]结果,而且它很好忽略它。同样,Prelude具有我们需要的内容:sequence_ :: Monad m => [m a] -> m ()执行列表中的每个monadic操作并忽略它们的返回值。

请注意,mapM_定义为

mapM_ f = sequence_ . map f

答案 1 :(得分:5)

map的类型是:

map :: (a -> b) -> [a] -> [b]

这意味着,由于putStr返回IO (),您的表达式将返回[IO ()]

您可以使用mapM_(从Prelude导入)忽略映射中的返回类型,并返回IO (),这是{{1}的合适返回类型}}:

main

Live demo