Генератор случайных чисел на Haskell: цепочка генерации случайных значений

Мне нужно сгенерировать 3 случайных значения в строке, где первое определяет, будут ли рассчитываться последние 2 значения:

randomEnemy :: World -> World
randomEnemy world@(World{enemies=e, rndGen}) = doR0 (randomR (0, 10) rndGen)
    where
        doR0 (a, g) =
            if a <= 1
                then doR1 (randomR (-562, 562) g)
                else world
        doR1 (a, g) = doR2 (a, randomR (-288, 288) g)
        doR2 (a, (b, g))  = world { enemies = e ++ [Enemy (a,b) (0,0)],
                                    rndGen=g }

Однако это не работает, и я не знаю почему. Он должен просто вычислить случайное значение между 0 и 10, которое определяет, должен ли случайный враг появляться или нет, тогда, если это так, он должен рассчитать еще 2 случайных числа для позиции, иначе вернет текущее состояние игры без изменений.

Хотя если я поменяю первый звонок на doR0 в doR1 это работает, что делает меня совершенно невежественным..

Если бы кто-нибудь мог помочь мне в этом, это было бы очень ценно!

С наилучшими пожеланиями, Skyfe.

РЕДАКТИРОВАТЬ: ошибки, которые он выбрасывает (sumarized):

No instance for (Ord a0) arising from a use of `DoR0`
The type variable `a0 is ambigious`
...
No instance for (Random a0) arising from a use of `RandomR`
The type variable `a0` is ambigious

1 ответ

Решение

Ваша проблема в том, что GHC не может понять, какого типа randomR (0, 10) rndGen должен вернуться. Единственное ограничение, которое вы наложили на это значение, заключается в том, что вы должны иметь возможность сравнить его с 1так что это должно удовлетворить Random, Num а также Ord. классы типов Другой doRN работать, потому что генерируемые вами случайные значения помещаются в структуру данных, в которой указаны конкретные типы, поэтому компилятор может определить, какой тип значения возвращать из других применений randomR, Вы можете исправить это, указав, что он должен вернуть Int в нескольких местах самым чистым является добавление сигнатуры типа в doR0 из (Int, StdGen) -> Worldтак что теперь компилятор может сделать вывод, что randomR (0, 10) rndGen возвращает значение типа (Int, StdGen) так как он потребляется doR0,

Другие вопросы по тегам