比较lambda内部的IO Int时出错

Aea*_*nus 0 io int lambda haskell

我在这里有一小段代码,我想在if语句中使用.代码是

getRandomInt :: (Int, Int) -> IO Int
getRandomInt (a, b) = do
    g <- newStdGen
    return . fst $ randomR (a, b) g
Run Code Online (Sandbox Code Playgroud)

然后再往下走......

if ((getRandomInt (0,1)) >>= (\x -> x == 1))
Run Code Online (Sandbox Code Playgroud)

根据我的理解,这应该编译randomInt == 1成if语句并在if语句中使用.代替; 我收到此错误:

word.hs:30:21:
    Couldn't match expected type `Bool' with actual type `IO b0'
    In the expression: ((getRandomInt (0, 1)) >>= (\ x -> x == 1))
    In a stmt of a 'do' block:
      if ((getRandomInt (0, 1)) >>= (\ x -> x == 1)) then
          getRandomVowel : (getWord $ len - 1)
      else
          getRandomConsonant : (getWord $ len - 1)
    In the expression:
      do { if ((getRandomInt (0, 1)) >>= (\ x -> x == 1)) then
               getRandomVowel : (getWord $ len - 1)
           else
               getRandomConsonant : (getWord $ len - 1) }
Run Code Online (Sandbox Code Playgroud)

对于任何明显的误解,我很抱歉,我刚开始学习Haskell.

GS *_*ica 5

类型(>>=)Monad m => m a -> (a -> m b) -> m b.在这种情况下m = IO.

所以你有两个问题:

首先,\x -> x == 1会返回一个Bool,而不是一个IO Bool,所以它不适合作为第二个参数(>>=).

你可以通过改变它来解决这个问题\x -> return (x == 1),但这不是一个非常干净的解决方案,然后你会发现结果是类型的IO Bool,而不是Bool.

这就是类型错误告诉你的 - if期望一个Bool参数,但它得到了IO something.

最干净的解决方案是将getRandomInt呼叫提升到一个单独的<-线路:

x <- getRandomInt (0,1)
if x == 1 then ...
Run Code Online (Sandbox Code Playgroud)