我的以下代码会出现此错误,该代码应创建一个由2个数组组成的数组,每个数组包含100个随机点:

type Point = (Float, Float)

initBg :: Int -> [[Point]]
initBg seed = [genRandom 100 [] rndGen, genRandom 100 [] rndGen]
   where genRandom amt res g = if amt == 0 then res else doR0 amt res (randomR (-562, 562) g)
         doR0 amt res (a, g)  = doR1 amt res (a, randomR (-288, 288) g)
         doR1 amt res (a, (b, g))  = genRandom (amt-1) (res++[a,b]) g
         rndGen = mkStdGen seed

谁能告诉我为什么会出现此错误以及如何解决该错误?

任何帮助将不胜感激,在此先感谢!

最好的祝福,
Skyfe。

编辑:错误:
No instance for (Random Point) arising from a use of `genRandom`
Possible fix: add an instance declaration for (Random Point)
In the expression: genRandom 100 [] rndGen
In the expression:
  [genRandom 100 [] rndGen, genRandom 100 [] rndGen]
In an equation for `initBg`:
...

最佳答案

因此,随机类包括Random类,它是可以随机生成的值的类(与您期望的生成器相反,可以为您生成随机值)。

您可以通过声明以下内容将对添加到Random类:

instance (Random x, Random y) => Random (x, y) where
    randomR ((lo_x, lo_y), (hi_x, hi_y)) g = ((rand_x, rand_y), g'')
        where (rand_x, g')  = randomR (lo_x, hi_x) g
              (rand_y, g'') = randomR (lo_y, hi_y) g'
    random g = ((rand_x, rand_y), g'')
        where (rand_x, g') = random g
              (rand_y, g'') = random g'

我知道这是一个复杂的定义,但是您的代码随后应该可以工作了。

警告:您的代码将使您生成列表[a,b]的a == b,这可能不是您想要的。您可能需要查看State中的Control.Monad.State.Lazy monad,您可以使用以下内容对其进行初始化:
state (randomR (1, 100)) :: State StdGen Int

此monad为您显式链接g参数,因此:
ghci> :m +System.Random
ghci> :m +Control.Monad.State.Lazy
ghci> let dice_3d6 = mapM (state . randomR) (replicate 3 (1, 6)) :: State StdGen [Int]
Loading package array-0.4.0.1 ... linking ... done.
Loading package deepseq-1.3.0.1 ... linking ... done.
Loading package bytestring-0.10.0.2 ... linking ... done.
Loading package Win32-2.3.0.0 ... linking ... done.
Loading package transformers-0.3.0.0 ... linking ... done.
Loading package old-locale-1.0.0.5 ... linking ... done.
Loading package time-1.4.0.1 ... linking ... done.
Loading package random-1.0.1.1 ... linking ... done.
Loading package mtl-2.1.2 ... linking ... done.
ghci> fst $ runState dice_3d6 (mkStdGen 1)
[6,5,2]
ghci> fst $ runState dice_3d6 (mkStdGen 1)
[6,5,2]
ghci> fst $ runState dice_3d6 (mkStdGen 2)
[6,4,1]
ghci> fst $ runState dice_3d6 (mkStdGen 3)
[6,4,5]

State StdGen monad中,您可以编写如下内容:
rand :: (Random r) -> (r, r) -> State StdGen r
rand (x, y) = state (randomR (x, y))

randPoint :: State StdGen (Float, Float)
randPoint = do
   x <- rand (-562, 562)
   y <- rand (-288, 288)
   return (x, y)

get100Points :: Int -> [(Float, Float)]
get100Points = fst . runState (sequence $ replicate 100 randPoint) . mkStdGen

我认为在没有上述类型类的情况下,您会得到100个随机点。但是我在猜测您的三功能相互递归在上面做什么。

关于haskell - Haskell : No instance for Random Point arising from a use of genRandom,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26674929/

10-15 21:32