module Data.Choose.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
data Choose = Choose !Int
!IntArray
unsafeAt :: Choose -> Int -> Int
unsafeAt (Choose _ arr) i = Arr.unsafeAt arr i
size :: Choose -> Int
size (Choose _ arr) = Arr.numElements arr
possible :: Choose -> Int
possible (Choose n _) = n
elems :: Choose -> [Int]
elems (Choose _ arr) = Arr.elems arr
instance Show Choose where
show c = "listChoose " ++ show n ++ " " ++ show k ++ " " ++ show es
where
n = possible c
k = size c
es = elems c
instance Eq Choose where
(==) c1 c2 = ( (possible c1 == possible c2)
&& (size c1 == size c2)
&& (elems c1 == elems c2)
)
data STChoose s = STChoose !Int
!(STIntArray s)
getSizeSTChoose :: STChoose s -> ST s Int
getSizeSTChoose (STChoose _ marr) = ArrST.getNumElements marr
sizeSTChoose :: STChoose s -> Int
sizeSTChoose (STChoose _ marr) = ArrST.numElementsSTIntArray marr
getPossibleSTChoose :: STChoose s -> ST s Int
getPossibleSTChoose (STChoose n _) = return n
possibleSTChoose :: STChoose s -> Int
possibleSTChoose (STChoose n _) = n
newSTChoose :: Int -> Int -> ST s (STChoose s)
newSTChoose n k = do
c@(STChoose _ marr) <- newSTChoose_ n k
ArrST.writeElems marr [0 .. k1]
return c
newSTChoose_ :: Int -> Int -> ST s (STChoose s)
newSTChoose_ n k = do
when (n < 0) $ fail "invalid number of possibilities"
when (k < 0 || k > n) $ fail "invalid outcome size"
liftM (STChoose n) $ ArrST.newArray_ k
unsafeGetElemSTChoose :: STChoose s -> Int -> ST s Int
unsafeGetElemSTChoose (STChoose _ marr) i = ArrST.unsafeRead marr i
unsafeSetElemSTChoose :: STChoose s -> Int -> Int -> ST s ()
unsafeSetElemSTChoose (STChoose _ marr) i x = ArrST.unsafeWrite marr i x
getElemsSTChoose :: STChoose s -> ST s [Int]
getElemsSTChoose (STChoose _ marr) = ArrST.readElems marr
setElemsSTChoose :: STChoose s -> [Int] -> ST s ()
setElemsSTChoose (STChoose _ marr) is = ArrST.writeElems marr is
unsafeFreezeSTChoose :: STChoose s -> ST s Choose
unsafeFreezeSTChoose (STChoose n marr) =
(liftM (Choose n) . ArrST.unsafeFreeze) marr
unsafeThawSTChoose :: Choose -> ST s (STChoose s)
unsafeThawSTChoose (Choose n arr) =
(liftM (STChoose n) . ArrST.unsafeThaw) arr
instance Eq (STChoose s) where
(==) (STChoose _ marr1) (STChoose _ marr2) =
ArrST.sameSTIntArray marr1 marr2