Haskell随机生成器:随机值的链生成
我需要在一行中生成3个随机值,其中第一个值决定是否计算最后2个值: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)
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
ifa中,您每次都返回相同的世界,谢谢您的评论。我试过了,但还是出错了。即使我输入: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