Haskell随机生成器:随机值的链生成

Haskell随机生成器:随机值的链生成,haskell,random,chain,Haskell,Random,Chain,我需要在一行中生成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)

我需要在一行中生成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 }

您的问题来自GHC无法确定应返回何种类型的
randomR(0,10)rndGen
。您对该值施加的唯一限制是,您需要能够将其与
1
进行比较,因此它需要满足
Random
Num
Ord
类型类。另一个
doRN
可以工作,因为您正在生成的随机值被放置到指定了具体类型的数据结构中,因此编译器可以推断从其他使用
randomR
返回的值的类型。您可以通过指定它需要在多个位置返回
Int
来解决此问题,最干净的方法是在
(Int,StdGen)->World
doR0
中添加一个类型签名,因此现在编译器可以推断
randomR(0,10)rndGen
返回类型
(Int,StdGen)的值
因为它是由
doR0

使用的,所以我非常非常推荐使用
MonadRandom
软件包。另外,如果在
where
前面没有40列空格,代码的可读性会更好。我想我知道你的问题。在
doR0
if
a中,您每次都返回相同的世界,谢谢您的评论。我试过了,但还是出错了。即使我输入:doR0(a,g)=doR1(randomR(-562562)g),它仍然会抛出一个错误,而如果我将其直接输入randofriend函数,它不会抛出一个错误,但如果我通过doR0调用它,它会抛出一个错误。我假设您已经解决了约束错误。如果有错误,总是把它贴在你的问题上,而不是仅仅说“不行”。出现的错误是因为编译器只知道要生成实现
Num
Ord
的随机值,但它不知道要使用哪种类型。将其更改为
doR0(randomR(0,10::Int)rndGen
,或者您可以向
:(Int,StdGen)->World的
doR0
添加类型签名
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