我正在制作自定义列表显示。这个概念确实很简单,但我一直遇到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
时,它在几次递归调用后最终有可能从行{{1 }},displayList [] = putStrLn ""
函数不支持将其作为输入。有人知道解决这个问题的方法吗?
答案 0 :(得分:4)
代码问题非常明显:正如编译器告诉您的那样,您正在尝试将字符串(((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