Haskell IO:无法将预期类型"IO a0"与实际类型匹配

Lau*_*oki 6 haskell

我是Haskell的新手,我试着理解如何正确地执行IO.

以下工作正常:

main = do
  action <- cmdParser
  putStrLn "Username to add to the password manager:"
  username <- getLine
  case action of
    Add -> persist entry
      where
        entry = Entry username "somepassword"
Run Code Online (Sandbox Code Playgroud)

以下结果导致编译错误:

main = do
  action <- cmdParser
  case action of
    Add -> persist entry
      where
        entry = Entry promptUsername "somepassword"

promptUsername = do
  putStrLn "Username to add to the password manager:"
  username <- getLine
Run Code Online (Sandbox Code Playgroud)

错误在这里:

Couldn't match expected type `IO b0' with actual type `[Char]'
Expected type: IO b0
  Actual type: String
In the expression: username
[...]
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?为什么第一个版本有效,而第二个版本没有?

我知道在Stack Overflow中有一些类似的问题,但是他们似乎都没有向我解释这个问题.

dan*_*rth 8

username是一个String,但是promptUsernameIO String.你需要做一些事情:

username <- promptUsername
let entry = Entry username "somepassword"
persist entry
Run Code Online (Sandbox Code Playgroud)

  • 我会扩大.这是令人困惑的一种做法.像`do {a; b < - c; db}`这样的代码实际上是`a >> =\_ - > c >> =\b - > db`的简写.那些来自命令世界的人认为这里的"< - "是一种赋值算子.它不是.do-notation中的每一行都转换为匿名函数,而`<-`标记了这种函数的参数.应该强烈鼓励人们阅读有关monad及其实际应用的知识,以熟悉它们. (6认同)