Haskell 使用Data.Vector.unbox.Mutable创建1..N的随机排列

Haskell 使用Data.Vector.unbox.Mutable创建1..N的随机排列,haskell,vector,Haskell,Vector,我想创建一个包含数字1到N的随机排列的列表。据我所知,可以在runST中使用VUM.swap,但由于我也需要随机数,我想我可以在IO monad中同时使用这两种方法 下面的代码生成: 预期类型:IO(VU.Vector Int),实际类型:IO(VU.Vector Int (矢量a0) 用于返回语句 import qualified Data.Vector.Unboxed as VU import qualified Data.Vector.Unboxed.Mutable as

我想创建一个包含数字1到N的随机排列的列表。据我所知,可以在runST中使用
VUM.swap
,但由于我也需要随机数,我想我可以在IO monad中同时使用这两种方法

下面的代码生成:

预期类型:IO(VU.Vector Int),实际类型:IO(VU.Vector Int (矢量a0)

用于返回语句

import qualified Data.Vector.Unboxed         as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import           System.Random

randVector :: Int -> IO (VU.Vector Int)
randVector n = do
  vector <- VU.unsafeThaw $ VU.enumFromN 1 n
  VU.forM_ (VU.fromList [2..VUM.length vector]) $ \i -> do
    j <- randomRIO(0, i) :: IO Int
    VUM.swap vector i j
  return $ VU.unsafeFreeze vector
import qualified Data.Vector.unbox为VU
将限定数据.Vector.unbox.Mutable导入为VUM
导入系统。随机
随机向量::Int->IO(VU.Vector Int)
随机向量n=do
向量do
j我会尝试(最后更新注释):


unsafeFreeze vector
已返回
IO(VU.vector Int)
。只需将最后一行更改为
VU.unsafeFreeze vector

另一方面,您应该迭代到
VUM.length vector-1
,因为
[x..y]
randomRIO
都使用包含范围。此外,您可以在这里使用普通的
表单
进行迭代,因为您只关心副作用

import           Control.Monad
import qualified Data.Vector.Unboxed         as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import           System.Random

randVector :: Int -> IO (VU.Vector Int)
randVector n = do
  vector <- VU.unsafeThaw $ VU.enumFromN 1 n
  forM_ [2..VUM.length vector - 1] $ \i -> do
    j <- randomRIO(0, i) :: IO Int
    VUM.swap vector i j
  VU.unsafeFreeze vector
import-Control.Monad
导入符合条件的Data.Vector.unbox为VU
将限定数据.Vector.unbox.Mutable导入为VUM
导入系统。随机
随机向量::Int->IO(VU.Vector Int)
随机向量n=do
向量do

这就成功了!返回语句就是问题所在。为什么使用返回嵌套向量?我永远也想不到。我使用了
VU.forM\uuu
而不是普通版本,因为我不确定在哪里可以找到普通版本。典型的输入大小是n=50,构建5000个随机向量,我无法想象for循环的不同会有多少秒的不同。我在
表单
边界上添加了注释,并编辑了
表单
性能上的位。
  VU.unsafeFreeze vector
import           Control.Monad
import qualified Data.Vector.Unboxed         as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import           System.Random

randVector :: Int -> IO (VU.Vector Int)
randVector n = do
  vector <- VU.unsafeThaw $ VU.enumFromN 1 n
  forM_ [2..VUM.length vector - 1] $ \i -> do
    j <- randomRIO(0, i) :: IO Int
    VUM.swap vector i j
  VU.unsafeFreeze vector