module Data.Permute.Base
where
import Control.Monad
import Control.Monad.ST
import Foreign
import Data.IntArray ( IntArray, STIntArray )
import qualified Data.IntArray as Arr
import qualified Data.IntArray as ArrST
newtype Permute = Permute IntArray
unsafeApply :: Permute -> Int -> Int
unsafeApply (Permute p) i = Arr.unsafeAt p i
size :: Permute -> Int
size (Permute p) = Arr.numElements p
elems :: Permute -> [Int]
elems (Permute p) = Arr.elems p
instance Show Permute where
show p = "listPermute " ++ show (size p) ++ " " ++ show (elems p)
instance Eq Permute where
(==) p q = (size p == size q) && (elems p == elems q)
newtype STPermute s = STPermute (STIntArray s)
getSizeSTPermute :: STPermute s -> ST s Int
getSizeSTPermute (STPermute marr) = ArrST.getNumElements marr
sizeSTPermute :: STPermute s -> Int
sizeSTPermute (STPermute marr) = ArrST.numElementsSTIntArray marr
newSTPermute :: Int -> ST s (STPermute s)
newSTPermute n = do
p@(STPermute marr) <- newSTPermute_ n
ArrST.writeElems marr [0 .. n1]
return $! p
newSTPermute_ :: Int -> ST s (STPermute s)
newSTPermute_ n = do
when (n < 0) $ fail "invalid size"
liftM STPermute $ ArrST.newArray_ n
unsafeGetElemSTPermute :: STPermute s -> Int -> ST s Int
unsafeGetElemSTPermute (STPermute marr) i = ArrST.unsafeRead marr i
unsafeSetElemSTPermute :: STPermute s -> Int -> Int -> ST s ()
unsafeSetElemSTPermute (STPermute marr) i x = ArrST.unsafeWrite marr i x
unsafeSwapElemsSTPermute :: STPermute s -> Int -> Int -> ST s ()
unsafeSwapElemsSTPermute (STPermute marr) i j = ArrST.unsafeSwap marr i j
getElemsSTPermute :: STPermute s -> ST s [Int]
getElemsSTPermute (STPermute marr) = ArrST.readElems marr
setElemsSTPermute :: STPermute s -> [Int] -> ST s ()
setElemsSTPermute (STPermute marr) is = ArrST.writeElems marr is
unsafeFreezeSTPermute :: STPermute s -> ST s Permute
unsafeFreezeSTPermute (STPermute marr) =
(liftM Permute . ArrST.unsafeFreeze) marr
unsafeThawSTPermute :: Permute -> ST s (STPermute s)
unsafeThawSTPermute (Permute arr) =
(liftM STPermute . ArrST.unsafeThaw) arr