Reputation: 879
I need to generate 3 random values in a row, where the first one determines whether the last 2 ones will be calculated or not:
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 }
However this is not working and I do not know why. It should simply calculate a random value between 0 and 10 which determines whether or not a random enemy should be spawned, then if so it should calculate 2 more random numbers for the position, otherwise return the current game state unchanged.
Although if I change the first call to doR0
to doR1
it DOES work, which leaves me totally clueless..
If anyone could help me out on this it'd be much appreciated!
Best regards, Skyfe.
EDIT: The errors it throws (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
Upvotes: 1
Views: 190
Reputation: 54078
Your problem comes from GHC not being able to figure out what type randomR (0, 10) rndGen
should return. The only constraints you've placed on this value is that you need to be able to compare it to 1
, so it needs to satisfy the Random
, Num
and Ord
typeclasses. The other doRN
work because the random values you're generating are being placed into a data structure that has concrete types specified, so the compiler can infer what type of value to return from the other uses of randomR
. You can fix this by specifying that it needs to return an Int
in several places, the cleanest is by adding a type signature to doR0
of (Int, StdGen) -> World
, so now the compiler can infer that randomR (0, 10) rndGen
returns a value of type (Int, StdGen)
since it's consumed by doR0
.
Upvotes: 2