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

dmw*_*w64 2 monads haskell

如何使用putStr和map输出字符串列表?我想做的事情如下:

s=["test1","test2"]
map putStr s
Run Code Online (Sandbox Code Playgroud)

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

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

cdk*_*cdk 7

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

我们这里有两个功能,

map :: (a -> b) -> [a] -> [b]
putStr :: String -> IO ()
Run Code Online (Sandbox Code Playgroud)

如果我们替代的类型putStrmap(即a ~ String,b ~ IO ())我们得到

map putStr :: [String] -> [IO ()]
Run Code Online (Sandbox Code Playgroud)

所以这需要一个字符串列表,并给我们一个IO ()行动列表; IO计算不返回任何有用的东西.

我们想把它[IO ()]转变为类似的东西,IO (...)因为我们需要IO成为最外层才能使用它main :: IO ()

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

sequence . map putStr :: [String] -> IO [()]
Run Code Online (Sandbox Code Playgroud)

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

注意,mapM_定义为

mapM_ f = sequence_ . map f
Run Code Online (Sandbox Code Playgroud)


Sho*_*hoe 5

类型map是:

map :: (a -> b) -> [a] -> [b]
Run Code Online (Sandbox Code Playgroud)

这意味着,因为putStr返回一个IO (),你的表达式将返回一个[IO ()].

相反,您可以使用mapM_(从中导入Prelude)忽略映射中的返回类型,并返回IO ()一个合适的返回类型main:

main = do
    let s=["test1","test2"]
    mapM_ putStr s
Run Code Online (Sandbox Code Playgroud)

Live demo