在新行上打印列表的元素

Lun*_*nar 39 haskell

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

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

所以这:

["1","2","2","4"]
Run Code Online (Sandbox Code Playgroud)

会给:

1
2
3
4
Run Code Online (Sandbox Code Playgroud)

Dav*_* V. 77

在大多数情况下,您不需要在列表上编程循环,它已经完成.要使用monadic函数循环遍历列表,您可以使用mapM(如果您不关心结果,则使用mapM_变体.)

如果你使用印刷品,["1","2","3","4"]你会得到:

Prelude> mapM_ print ["1","2","3","4"]
"1"
"2"
"3"
"4"
Prelude> 
Run Code Online (Sandbox Code Playgroud)

打印实际上是:

print :: Show a => a -> IO ()
print x = putStrLn (show x)
Run Code Online (Sandbox Code Playgroud)

显示功能使字符串"1"转换为"\"1\"",putStrLn打印出和换行.

如果用putStrLn替换打印,删除转换步骤并直接打印字符串:

Prelude> mapM_ putStrLn ["1","2","3","4"]
1
2
3
4
Prelude> 
Run Code Online (Sandbox Code Playgroud)

现在我想提供另一种解决方案.Haskell的处理方式是以纯粹的方式尽可能多地做,并且只在需要时使用IO.

所以在这种情况下,我们可以连接所有要打印\n的字符串,并立即打印所有字符串.

要加入所有字符串,有一个方便的功能:取消显示

Prelude> unlines ["1","2","3","4"]
"1\n2\n3\n4\n"
Prelude> 
Run Code Online (Sandbox Code Playgroud)

现在你只需要打印出来; 请注意,unlines在列表的最后一项之后放置换行符,因此我们将使用putStr而不是putStrLn

Prelude> putStr ( unlines ["1","2","3","4"] )
1
2
3
4
Prelude> 
Run Code Online (Sandbox Code Playgroud)

  • 如果列表非常大,那么`unlines`会使用两倍的内存,还是Haskell在这种情况下会变得懒惰? (7认同)
  • 我认为,即使输出相同,unlines也是一个"更正确"的解决方案. (5认同)

Alv*_*ivi 11

你的职责是:

printElements :: [String] -> IO()
printElements [] = return ()
printElements (x:xs) = do putStrLn x
                          printElements xs
Run Code Online (Sandbox Code Playgroud)

如果你已经了解monad,你可以使用mapM_函数:

printElements :: [String] -> IO()
printElements = mapM_ putStrLn
Run Code Online (Sandbox Code Playgroud)

注意:也许你必须阅读lyah的第8章.

  • `printElements(x:xs)= putStrLn x >> printElements xs`是编写第一个函数的另一种方法. (4认同)

sha*_*ang 9

您可以使用mapM_来调用putStrLn每个元素,而不是显式递归.它的作用类似于常规map列表,但与monadic函数(因此为"M")一起使用.当你只关心副作用(在这种情况下,打印)并且不关心映射函数的结果时,使用下划线变体.

printElements :: [String] -> IO ()
printElements = mapM_ putStrLn
Run Code Online (Sandbox Code Playgroud)