我需要连续生成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
答案 0 :(得分:2)
您的问题来自GHC无法确定应返回的randomR (0, 10) rndGen
类型。您对此值的唯一限制是您需要能够将其与1
进行比较,因此需要满足Random
,Num
和Ord
类型类。另一个doRN
起作用,因为您生成的随机值被放置到指定了具体类型的数据结构中,因此编译器可以推断从randomR
的其他用途返回的值的类型。您可以通过指定它需要在多个位置返回Int
来解决此问题,最简单的方法是向doR0
的{{1}}添加类型签名,因此编译器现在可以推断{ {1}}返回(Int, StdGen) -> World
类型的值,因为randomR (0, 10) rndGen
消耗了它。