[英]How to use Unboxed Mutable vector
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
我正在實現 QuickSort 算法並選擇Data.Vector.Unboxed.Mutable
我完全迷失了兩個問題:
Monad
: IO
或ST
ST
中獲取價值。 誰能告訴我如何打印new0
?解決方案:
我從這個示例代碼中得到了一些靈感
為了更好地理解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
function需要一個適用於s
的所有可能選擇的操作。 這意味着不可能返回任何包含s
東西。 由於所有可變的東西在其類型簽名中都有s
,因此這加強了我們的保證。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.