我在玩定制列表显示。这个概念非常简单,但我总是得到一个IO()错误。我的代码是:
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))得到错误的行的特定部分是displayList theRest,而不是putStrLn ((show firstUnit) ++部分。
我想我理解正在发生的事情,即当displayList theRest在一行中被调用时有错误时,经过几次递归调用之后,它最终有可能从行displayList [] = putStrLn ""返回IO()类型,这在putStrLn函数中不受支持。有谁知道解决这个问题的方法吗?
发布于 2019-03-05 23:28:12
问题
代码的问题很明显:正如编译器告诉您的,您正在尝试将字符串(((show firstUnit) ++)与IO() (函数的返回类型)连接起来。
解决方案
该解决方案可以采取两种途径:要么希望函数返回整个字符串,然后将其全部打印在一个字符串中,要么只需逐个递归地打印。我的意思是:
返回字符串
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我想你可以看到这个版本是如何更容易阅读。还请注意,print :: Show a => a -> IO()与putStrLn . show完全一样工作。
https://stackoverflow.com/questions/55013019
复制相似问题