如何在Haskell的IO monad中包装char文字?

Jam*_*ter 0 monads haskell do-notation io-monad

我知道您应该将要对结果执行的操作包装在monad中,而不是从monad中拆包。

我找不到如何做到这一点的任何对白痴友好的例子。

例如,我想做这样的事情:

myFunction = do
    c <- getChar
    if (c == 'q')
        then putStrLn "take action 1"
        else putStrLn "take action 2"
Run Code Online (Sandbox Code Playgroud)

但是您不能直接将char文字与IO Char进行比较。

GHCi版本是8.4.4。

错误信息:

[2之1]编译Lib(/Users/jamesstrieter/hask-tink/src/Lib.hs,已解释)

/Users/jamesstrieter/hask-tink/src/Lib.hs:66:18:错误:•无法将预期类型'IO char'与实际类型'Char'匹配•在第二个参数'(==)' ,即“ q”在表达式中:x =='q'在'what2do'的等式中:what2do x = x =='q'•相关绑定包括x :: IO字符(绑定在/ Users / jamesstrieter /hask-tink/src/Lib.hs:66:9)what2do :: IO字符-> Bool(绑定到/Users/jamesstrieter/hask-tink/src/Lib.hs:66:1)| 66 | what2do x = x =='q'| ^^^失败,未加载任何模块。

puh*_*len 7

您发布的代码看起来完全正确并且可以正常运行。

做注释是在monad中使用价值的一种方式。

c <- getChar在do块中,将c绑定到IO Char您所获得的char中getChar。您可以c == 'q'在这里进行比较,因为c是纯字符,而不是IO Char

为了回答您的直接问题,您可以使用该return函数将纯值放入任何单声道,包括IO,因此return 'q'将字符文字“ q”“包装”到单声道中。在这种情况下,这不是您想要的,已经在寻找的代码就是您想要的。

  • 只是一个nitpick,`getChar`不会“返回`IO Char`,而是* IO Char。 (6认同)

Tho*_*son 5

但是您不能直接将字符文字与 IO 字符进行比较。

当然,但是当您“绑定” IO 操作的结果时,它不再是 anIO Char而只是 aChar所以这就是它起作用的原因。

换句话说:

Prelude> :t getChar
getChar :: IO Char
Prelude> c <- getChar
x
Prelude> :t c
c :: Char
Run Code Online (Sandbox Code Playgroud)