Если заявление с использованием IO Int haskell - PullRequest
0 голосов
/ 06 февраля 2019

У меня есть игра, пользователь против компьютера, и я хочу случайным образом выбрать, кто запускает игру.У меня есть

a = getStdRandom $ randomR (0, 1)

Это получает случайное число 0 или 1. Однако это IO Int, поэтому у меня не может быть оператора if, сравнивающего его с числом типа

if a == 0 then userStarts else computerStarts 

Я пытался сравнить IO Int с IO Int, и это не работает, и я также пытался

Преобразование IO Int в Int

IЯ очень новичок в 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 голосов
/ 06 февраля 2019

Когда вы говорите a = getStdRandom $ randomR (0,1), вы говорите: «Пусть a будет действием для получения случайного значения между 0 и 1».То, что вы хотите, находится в блоке do какой-либо функции a <- getStdRandom $ randomR (0,1), который «пусть a будет результатом выполнения действия по получению случайного значения в диапазоне от 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"

NB. Я указал, что 1 - это int, иначе компилятор не узнает, хотите ли вы случайное int, int64, double, float или что-то еще полностью.

EDIT: @monocell makeхороший момент, что генерация int в диапазоне только для получения логического значения является несколько косвенной.Вы можете просто сгенерировать логический результат, и для этого не требуется диапазон:

  a <- getStdRandom random
  if a then userStarts else computerStarts
0 голосов
/ 06 февраля 2019

Не знаете, как выглядит ваш код, но вы пытались делать то, что рекомендует связанный ресурс (используя блок do)?

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

Это даст вам доступ к result, которыйтот же тип, что и 0 и 1.

Можете ли вы показать свой код / ​​полученную ошибку?

...