自身数据类型的haskell随机实例 [英] haskell random instance of own datatype
问题描述
我正在使用Graphics.gloss开发Haskell制作的小行星游戏.现在,我已经为小行星定义了这样的数据类型:
I am working on an Asteroid game made in Haskell with Graphics.gloss. Now I have defined a datatype for the asteroids like this:
data Asteroid = Asteroid { asteroidPos:: Point,
asteroidVel :: Vector,
asteroidSize :: Float }
因此它具有一个由点定义的位置,由向量定义的速度及其大小.现在,我想知道如何为该数据类型编写一个Random实例,以便在随机时间以随机速度在随机位置出现一个新的小行星.有人知道我该怎么做吗?
So that it has a Position defined by a point, a velocity defined by a vector and it's size. Now I want to know how I could write an instance of Random for this datatype so that a new asteroid appears at a random time, on a random place with a random velocity. Does anyone know how I can accomplish this?
推荐答案
Float
已有一个Random
实例.假设您还有Vector
和Point
的Random
实例,则可以使用它们为Asteroid
定义Random
实例:
There's already a Random
instance for Float
. Assuming that you also have Random
instances for Vector
and Point
, you can use them to define a Random
instance for Asteroid
:
instance Random Asteroid where
randomR (Asteroid pl vl sl, Asteroid ph vh sh) g =
let (p, g1) = randomR (pl, ph) g
(v, g2) = randomR (vl, vh) g1
(s, g3) = randomR (sl, sh) g2
in (Asteroid p v s, g3)
random g =
let (p, g1) = random g
(v, g2) = random g1
(s, g3) = random g2
in (Asteroid p v s, g3)
randomR
函数采用从最小(低)到最大(高)的值范围.如何定义诸如Asteroid
之类的复杂值的有意义范围,我将任由您自己决定;在这里,我只是假设您可以传递一个高低的Asteroid
值.
The randomR
function takes a range of values, from minimum (low) to maximum (high). How you define a meaningful range of a complex value like Asteroid
, I'll leave up to you; here, I'm simply assuming that you can pass a low and high Asteroid
value.
第一步,通过调用randomR
将基础Random
实例用于Point
. p
是随机生成的Point
值,而g1
是下一个要使用的随机生成器值.
The first step uses the underlying Random
instance for Point
by calling randomR
. p
is a randomly generated Point
value, and g1
is the next random generator value to use.
同样,v
是随机生成的Vector
值,由Vector
的基础实例生成.
Likewise, v
is a randomly generated Vector
value, generated by the underlying instance for Vector
.
最后,s
是Float
由randomR
生成的Float
.
返回值是一个新的Asteroid
值,由p
,v
和s
加上最新的生成器g3
组成.
The return value is a new Asteroid
value composed from p
, v
, and s
, plus the most recent generator g3
.
random
的实现遵循相同的模板.
The implementation of random
follows the same template.
例如,您可以使用更漂亮的形式编写此代码.使用MonadRandom
,但是对于初学者来说,我将代码保留为原始格式以显示其工作原理.
You could write this code in a prettier form, using e.g. using MonadRandom
, but for starters, I left the code in its raw form to show how it works.
这篇关于自身数据类型的haskell随机实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!