gpt4 book ai didi

haskell - 使用 Data.Vector.Unboxed.Mutable 创建 1..N 的随机排列

转载 作者:行者123 更新时间:2023-12-02 13:47:40 25 4
gpt4 key购买 nike

我想创建一个包含数字 1 到 N 的随机排列的列表。据我了解,可以在 runST 中使用 VUM.swap ,但因为我需要随机数我也认为我可以在 IO monad 中同时执行这两项操作。

下面的代码产生:

Expected type: IO (VU.Vector Int), Actual type: IO (VU.Vector (VU.Vector 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

我不太清楚为什么返回向量是嵌套的。我必须使用 VU.fold1M_ 来代替吗?

最佳答案

unsafeFreeze 向量 已返回IO (VU.Vector Int)。只需将最后一行更改为VU.unsafeFreeze向量即可。

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

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

我查看了生成的代码,似乎使用 GHC 7.10.3 forM_ 编译为一个有效的循环,而 VU.forM_ 保留了中间列表并且肯定是明显变慢(这是我对 forM_ 的预期结果,但我不确定 VU.forM_)。

关于haskell - 使用 Data.Vector.Unboxed.Mutable 创建 1..N 的随机排列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37243638/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com