gpt4 book ai didi

haskell - 如何使用未装箱的可变向量

转载 作者:行者123 更新时间:2023-12-03 15:53:41 25 4
gpt4 key购买 nike

import           Control.Monad.ST
import Data.STRef

import qualified Data.Vector.Unboxed as V
import qualified Data.Vector.Unboxed.Mutable as MV

-- what the heck is that s?
new0 :: (MV.Unbox a, Num a) => ST s (MV.STVector s a)
new0 = do
v <- MV.new 10
MV.write v 1 10
MV.write v 2 10
return v

new1 :: (MV.Unbox a) => IO (MV.IOVector a)
new1 = MV.new 10

new2 :: (MV.Unbox a, Num a) => IO (MV.STVector RealWorld a)
new2 = do
v <- MV.new 10
MV.write v 1 10
return v
我正在实现快速排序算法,我选择 Data.Vector.Unboxed.Mutable我完全迷失了两个问题:
  • 如何正确选择Monad : IOST
  • 如何从 ST 中获取值.谁能告诉我如何打印new0 ?

  • 解决方案:
    我从中得到了一些启发 example code
    为了更好地理解 ST monad,查看原论文: Lazy Functional State Threads
    这是一个代码片段,展示了如何使用可变向量进行快速排序:
    import           Control.Monad.Primitive
    import Control.Monad.ST (runST)
    import Prelude hiding (read)

    import Data.List (partition)
    import qualified Data.Vector.Unboxed as V
    import qualified Data.Vector.Unboxed.Mutable as M

    partitionV :: (PrimMonad m, Ord a, V.Unbox a)
    => M.MVector (PrimState m) a -> Int -> Int -> m Int
    partitionV v p r = do
    let i = p
    x <- M.unsafeRead v r
    go i p x
    where
    go i j x | j < r = do
    jv <- M.unsafeRead v j
    if jv < x
    then M.unsafeSwap v i j >> go (i+1) (j+1) x
    else go i (j+1) x
    go i _ _ = do
    M.unsafeSwap v i r
    return i

    quickSortV :: (PrimMonad m, Ord a, V.Unbox a)
    => M.MVector (PrimState m) a -> m ()
    quickSortV v | M.length v < 2 = return ()
    quickSortV v = do
    i <- partitionV v 0 (M.length v - 1)
    quickSortV (M.unsafeSlice 0 i v)
    quickSortV (M.unsafeSlice (i + 1) (M.length v - 1 - i) v)
    -- note the difference between for loop and recursive call

    test l = runST $ do
    mv <- V.thaw l
    quickSortV mv
    V.freeze mv

    quickSort :: (Ord a) => [a] -> [a]
    quickSort [] = []
    quickSort (x : xs) =
    let (lt, gt) = partition (<= x) xs
    in quickSort lt ++ [x] ++ quickSort gt

    最佳答案

    ST monad 用于当您想要获取一些不可变数据,使其暂时可变,对其进行处理并再次使其不可变时。特别是,无法从 ST 返回可变结果。单子(monad)(按设计)。
    特别是,STVector是可变的,所以它永远不会离开 ST单子(monad)。所以没有办法“打印出来”new0 .您必须将其转换为不可变的东西才能将其从 ST 中返回。单子(monad)。
    如果你想改变一些东西,打印出来,再改变一点,打印出来等等,你可能想要 IO monad。 ST monad 用于使某些东西暂时可变,最终产生一个普通的即时结果。
    关于s类型变量:这是一个小技巧,强制执行可变数据不能离开的属性ST . runST函数需要一个对 s 的所有可能选择都有效的操作.这意味着不可能返回任何包含 s 的内容。 .因为所有可变的东西都有 s在其类型签名中,这加强了我们的保证。

    关于haskell - 如何使用未装箱的可变向量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66903260/

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