尝试显示列表时出现putStrLn IO()错误

时间:2019-03-05 23:04:30

标签: haskell io

我正在制作自定义列表显示。这个概念确实很简单,但我一直遇到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 ""函数不支持将其作为输入。有人知道解决这个问题的方法吗?

1 个答案:

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