新矩阵的Haskell RandomGen

新矩阵的Haskell RandomGen,haskell,matrix,Haskell,Matrix,我必须在haskell中实现此功能: insertRandomNumber :: RandomGen g => [[Int]] -> g -> ([[Int]], g) 该函数在我的矩阵中的任意位置插入一个随机数。我只能在有0的位置插入。矩阵大小为4 x 4。我有这个: insertRandomNumber :: RandomGen g => [[Int]] -> g -> ([[Int]], g) insertRandomNumber mat g =

我必须在haskell中实现此功能:

insertRandomNumber :: RandomGen g => [[Int]] -> g -> ([[Int]], g)
该函数在我的矩阵中的任意位置插入一个随机数。我只能在有0的位置插入。矩阵大小为4 x 4。我有这个:

insertRandomNumber :: RandomGen g => [[Int]] -> g -> ([[Int]], g)
insertRandomNumber mat g =
    let (pos,_) = randomR (1,16) g
        ok = free (pos `div` 4) (pos `mod` 4) mat
    in if ok == True 
       then newmatrix pos mat 
       else insertRandomNumber mat g
问题是,如果第一个位置没有空闲,我的程序将阻塞其他位置。
我希望您能给我一个示例,说明如何使用randomgen将随机数插入到自由随机位置。

您需要保留新的随机数生成器,并传递该生成器,而不是旧的生成器。如果不这样做,则意味着您将始终在每次迭代和循环中生成相同的
pos

代码:

let (pos,_) = randomR (1,16) g
在这里,您将显式忽略新的RNG状态。相反:

let (pos,newGen) = randomR (1,16) g
然后,您传递了旧的生成器,它将生成完全相同的
pos

in if ok == True then newmatrix pos mat else insertRandomNumber mat g
相反,您应该传递新的生成器状态:

in if ok == True then newmatrix pos mat else insertRandomNumber mat newGen

您可以将此问题分为三部分:枚举包含0的所有索引,从中选择一个随机索引,并在所选索引处插入一个随机数。比如说:

insertRandomNumber :: RandomGen g => [[Int]] -> g -> ([[Int]], g)
insertRandomNumber mat g0 = case validPositions mat of 
                             [] -> (mat, g0)
                             xs -> let (i,g1)  = randomR (0, length xs - 1) g0
                                       (v, g2) = randomR (1,100 :: Int) g1 
                                    in (replaceAt mat (xs !! i) v, g2)

我将让您编写函数
validPositions
replaceAt

提示:风格挑剔:
ok==True
是多余的。