2014-10-31 24 views
1

我得到這個錯誤我下面的代碼應該創建2個陣列,每個包含100個隨機點的陣列產生的:哈斯克爾:沒有實例隨機點從使用genRandom

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`: 
... 
+0

發佈錯誤(全部)。 – chi 2014-10-31 12:44:21

+0

和你指的類型/類。而且:如果格式化爲稍微更傳統的線寬,您的代碼將更具可讀性。 – leftaroundabout 2014-10-31 12:49:35

+0

錯誤和格式化代碼有點更新後,不知道你指的是我指的類型/類是什麼? – user2999349 2014-10-31 12:52:57

回答

3

所以Random類包括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,您可以用之類的初始化:

state (randomR (1, 100)) :: State StdGen Int 

這個單子明確鏈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單子你可以寫這樣的東西:

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個隨機點沒有上面的那些類型類。但我在猜測你的三元函數相互遞歸在上面做了什麼。

+0

謝謝你的魅力! – user2999349 2014-11-01 15:13:02