如果使用IO Int haskell的语句

时间:2019-02-06 16:05:23

标签: haskell random functional-programming haskell-stack io-monad

我有一个游戏,用户与计算机,我想随机选择谁启动游戏。我有

a = getStdRandom $ randomR (0, 1)

这将得到一个随机数0或1。但是它是一个IO Int,因此我无法通过if语句将其与类似

的数字进行比较。
if a == 0 then userStarts else computerStarts 

我尝试将IO IntIO Int进行比较,但它不起作用,并且我也尝试过

Converting IO Int to Int

我对Haskell还是陌生的,不确定如何解决这个问题。请求的代码详细信息:

randomNumber =  getStdRandom $ randomR (0, length symbols - 5) --  this will be 0 or 1
randomNumber2 =  getStdRandom $ randomR (0, length symbols - 5) -- according to 
                     -- the solution I need another function returning IO int.

a = do
   x <- randomNumber
   randomNumber2 $ pureFunction x

我得到的错误:

• Couldn't match expected type ‘t0 -> IO b
                  with actual type ‘IO Int’
    • The first argument of ($) takes one argument,
      but its type ‘IO Int’ has none
      In a stmt of a 'do' block: randomNumber2 $ pureFunction x
      In the expression:
        do x <- randomNumber
           randomNumber2 $ pureFunction x

    • Relevant bindings include
        a :: IO b
          (bound at Path:87:1)

    randomNumber2 $ pureFunction x

Path:89:20: error:
    Variable not in scope: pureFunction :: Int -> t0

     randomNumber2 $ pureFunction x

2 个答案:

答案 0 :(得分:12)

当您说a = getStdRandom $ randomR (0,1)时,您的意思是“让它成为获得0到1之间的随机值的动作”。您想要的是在某个函数的do块a <- getStdRandom $ randomR (0,1)中,它是“让它成为执行获取0到1之间的随机值的动作的结果”。

因此:

import System.Random

main :: IO ()
main = do
  a <- getStdRandom $ randomR (0, 1 :: Int)
  if a == 0 then userStarts else computerStarts

-- Placeholders for completeness
userStarts, computerStarts :: IO ()
userStarts = putStrLn "user"
computerStarts = putStrLn "computer"

我指定了1是一个int,否则编译器不会知道您是否想要一个随机的int,int64,double,float或其他任何内容。

编辑:@monocell提出了一个很好的观点,即仅仅为了获取布尔值而在范围内生成一个int是间接的。您可以直接生成布尔结果,并且不需要范围:

  a <- getStdRandom random
  if a then userStarts else computerStarts

答案 1 :(得分:3)

不确定代码的外观,但是您是否尝试过执行链接资源的建议(使用do块)?

do
   (result, newGenerator) <- randomR (0, 1) generator
   -- ...

这将使您可以访问result0属于同一类型的1

您可以显示代码/错误吗?