如何使用putStr和map输出字符串列表?我想做点什么:
s=["test1","test2"]
map putStr s
但是对monad没有经验,也不知道如何正确...
非常欢迎任何形式的提示!
答案 0 :(得分:7)
这里正确的做法是使用mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
。但是,如果您想了解一些有用的Prelude
函数......
我们这里有两个功能,
map :: (a -> b) -> [a] -> [b]
putStr :: String -> IO ()
如果我们将putStr
的类型替换为map
(即。a ~ String
,b ~ 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)