在新行上打印列表的元素

时间:2011-03-13 13:51:33

标签: haskell

我正在尝试将列表中的元素打印到新行上,但我无法使其工作;

printElements :: [String] -> IO()
printElements (x:xs) =  print x (some kind of newline, then loop?) printElements xs

所以这个:

["1","2","2","4"]

会给:

1
2
3
4

3 个答案:

答案 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