Haskell 尝试显示列表时发生Putstrn IO()错误
我在做自定义列表显示。这个概念非常简单,但我一直遇到IO错误。我的代码是:Haskell 尝试显示列表时发生Putstrn IO()错误,haskell,io,Haskell,Io,我在做自定义列表显示。这个概念非常简单,但我一直遇到IO错误。我的代码是: displayList :: [Int] -> IO() displayList [] = putStrLn "" displayList (firstUnit:theRest) = putStrLn (show firstUnit ++ "\n" ++ displayList theRest) 我得到的错误代码是: • Couldn't
displayList :: [Int] -> IO()
displayList [] = putStrLn ""
displayList (firstUnit:theRest) = putStrLn (show firstUnit ++ "\n" ++
displayList theRest)
我得到的错误代码是:
• Couldn't match expected type ‘[Char]’ with actual type ‘IO ()’
• In the second argument of ‘(++)’, namely ‘(displayList theRest)’
In the first argument of ‘putStrLn’, namely
‘((show firstUnit) ++ (displayList theRest))’
In the expression:
putStrLn ((show firstUnit) ++ (displayList theRest))
获取错误的行的特定部分是显示列表,而不是putStrLn show firstUnit++部分
我想我理解了正在发生的情况,即当在带有错误的行中调用displayList theRest时,经过几次递归调用后,它最终可能会从行displayList[]=putStrLn返回一个IO类型,这在putStrLn函数中不支持作为输入。有人知道解决这个问题的方法吗?这个问题
代码的问题相当明显:正如编译器告诉您的,您试图将字符串show firstUnit++与函数返回类型的IO连接起来
解决方案
该解决方案可以采用两种途径:要么需要一个返回整个字符串的函数,然后将其全部打印在一个字符串中,要么只是一步一步地递归打印。我的意思是:
返回字符串
这种方法很好,但我认为它既不整洁也不清晰
更好的版本
我想你可以看到这个版本是如何更容易阅读的。还要注意,print::Show a=>a->IO的工作原理与putStrLn完全相同。showdisplayList在任何情况下都不会返回字符串。它总是返回IO,所以…++显示列表中的列表没有意义。你最好先构造这个函数并返回一个字符串,然后根据需要打印字符串。问题是你试图连接一个字符串或[Char],这意味着displayList的结果也是一样的,这就是IO——很明显你不能这样做。我不确定您希望如何输出它,但您可能希望调用putStrLn show firstUnit,然后递归地调用rest上的displayList。然后我指的是对2个IO操作进行排序,或者在do块中,或者使用>>操作符,这是相同的,这是do块转换成的。在任何编程语言中,包括命令式语言,都会遇到同样的问题。您需要弄清楚是否希望displayList生成并返回字符串,或者它是否应该输出内容而不返回任何内容。您当前拥有的是printf%d\n%s,firstUnit,printftheRest…甚至更好的版本:displayList ns=mapM\u print ns
displayList :: [Int] -> IO()
displayList = putStrLn . helper
where
helper :: [Int] -> String
helper [] = ""
helper (n:ns) = show n ++ "\n" ++ helper ns
displayList' :: [Int] -> IO()
displayList' [] = putStrLn ""
displayList' (n:ns) = putStrLn (show n) >> displayList' ns