我正在尝试将列表中的元素打印到新行上,但我无法使其工作;
printElements :: [String] -> IO()
printElements (x:xs) = print x (some kind of newline, then loop?) printElements xs
所以这个:
["1","2","2","4"]
会给:
1
2
3
4
答案 0 :(得分:73)
在大多数情况下,您不需要在列表上编程循环,它已经完成了。要使用monadic函数循环遍历列表,如果您不关心结果,则可以使用mapM(及其mapM_变体。)
如果您使用print,则会["1","2","3","4"]
获得:
Prelude> mapM_ print ["1","2","3","4"]
"1"
"2"
"3"
"4"
Prelude>
print实际上是:
print :: Show a => a -> IO ()
print x = putStrLn (show x)
show函数会将字符串"1"
转换为"\"1\""
,putStrLn会打印该字符串和换行符。
如果您将print替换为putStrLn,则会删除转换步骤并直接打印字符串:
Prelude> mapM_ putStrLn ["1","2","3","4"]
1
2
3
4
Prelude>
现在我想提供另一种解决方案。 Haskell的处理方式是以纯粹的方式尽可能多地做,并且只在需要时使用IO。
因此,在这种情况下,我们可以使用\n
连接要打印的所有字符串,并立即打印所有字符串。
要加入所有字符串,有一个方便的功能:unlines
Prelude> unlines ["1","2","3","4"]
"1\n2\n3\n4\n"
Prelude>
现在你只需要打印出来;请注意unlines在列表的最后一项之后添加换行符,因此我们将使用putStr代替putStrLn
Prelude> putStr ( unlines ["1","2","3","4"] )
1
2
3
4
Prelude>
答案 1 :(得分:11)
您的职能是:
printElements :: [String] -> IO()
printElements [] = return ()
printElements (x:xs) = do putStrLn x
printElements xs
如果您已经了解monad,可以使用mapM_
函数:
printElements :: [String] -> IO()
printElements = mapM_ putStrLn
注意:也许你必须阅读lyah的第8章。
答案 2 :(得分:9)
您可以使用mapM_
为每个元素调用putStrLn
,而不是显式递归。它与列表的常规map
类似,但与monadic函数(因此为“M”)一起使用。当你只关心副作用(在这种情况下,打印)并且不关心映射函数的结果时,使用下划线变体。
printElements :: [String] -> IO ()
printElements = mapM_ putStrLn