我试图在runST
语句中使用随机生成器,并在使用后返回生成器,以便可以在别处使用它。从运行器返回随机发生器
如果我只返回一个向量,代码将会编译,但是当向return语句添加生成器时,编译失败。如果我正确理解错误消息,它说传递给monadic fold的函数不会修改处于同一状态的向量,但我无法弄清楚为什么它会编译,如果我从return语句中省略随机生成器。
这编译:
import Control.Monad
import Control.Monad.ST
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import System.Random
randVector :: (RandomGen g) => Int -> g -> VU.Vector Int
randVector n g = runST $ do
vector <- VU.unsafeThaw (VU.enumFromN 1 n)
let step g i = do let (j,g') = randomR (1,n) g
VUM.swap vector i j
return g'
g' <- foldM step g [1..VUM.length vector-1]
VU.unsafeFreeze vector
但这并不:
randVector' :: (RandomGen g) => Int -> g -> (VU.Vector Int, g)
randVector' n g = runST $ do
vector <- VU.unsafeThaw (VU.enumFromN 1 n) :: ST s (VUM.MVector s Int)
let step g i = do let (j,g') = randomR (1,n) g
VUM.swap vector i j
return g'
g' <- foldM step g [1..VUM.length vector-1]
(VU.unsafeFreeze vector, g')
与冷冻矢量和随机数发生器return语句产生以下错误:
Couldn't match expected type
ST s (VU.Vector Int, g)
with actual type(m0 (VU.Vector Int), g)