如何打印 IO 字符串 - "Couldn't match type ‘IO String’ with ‘[Char]’ Expected type: String Actual type: IO String"

How to print IO String - "Couldn't match type ‘IO String’ with ‘[Char]’ Expected type: String Actual type: IO String"

我希望此函数打印给定的 IO String

day :: IO String -> IO ()
day p2 = do
  putStr "p2: "
  putStrLn p2

但是编译器说它需要[Char],但据我所知它与String基本相同,所以我的问题是如何打印出IO String?

这也是 stack run 输出的错误:

    • Couldn't match type ‘IO String’ with ‘[Char]’
      Expected type: String
        Actual type: IO String
    • In the first argument of ‘putStrLn’, namely ‘p2’
      In a stmt of a 'do' block: putStrLn p2
      In the expression: do putStrLn p2    • Couldn't match type ‘IO String’ with ‘[Char]’
      Expected type: String
        Actual type: IO String
    • In the first argument of ‘putStrLn’, namely ‘p2’
      In a stmt of a 'do' block: putStrLn p2
      In the expression: do putStrLn p2
   |
17 |   putStrLn p2
   |            ^^

我尝试 putStr ("p2: " ++ p2) 并使用 print 但没有成功:(

编译器的报错信息其实很清楚。 putStrLn 的参数必须是 String(或 [Char],这两种类型是彼此的同义词),但您的 p2 不是 String但是 IO String.

同样的根本错误发生在你说你尝试过的其他两件事中——他们无法解决这个问题。

你想做什么还不是很清楚。我看到两种可能性:

  • 如果您只是想打印出一个字符串,那么您根本不希望输入是一个 IO String,而是一个简单的 String。如果您只是相应地更改类型签名,这将毫无问题地编译。

  • 也许您确实想要将类型为 IO String 的操作(例如 getLine)作为输入。在这种情况下,您可以使用 do 表示法(无论如何您已经在使用)来绑定操作的 output,这是一个实际的 String,到一个变量,然后用那个调用 putStrLn

    day :: IO String -> IO ()
    day p2 = do
       putStr "p2: "
       s <- p2
       putStrLn s