user5402 answer - , , Data.Vector . , , . thunks, , , .
. , . , vector, . .
, , indexM . , . , (, thunk) . unsafe (unsafeIndexM, unsafeIndex unsafeWrite ).
{-# Language ScopedTypeVariables #-}
module Insert where
import qualified Data.Vector as V
import Data.Vector (Vector)
import qualified Data.Vector.Mutable as MV
import Data.Vector.Mutable (MVector)
import Control.Monad.ST
insertElem :: forall a . Ord a => a -> Vector a -> Vector a
insertElem e v = V.create act
where
act :: forall s . ST s (MVector s a)
act = do
mv <- MV.new (V.length v + 1)
let
start :: Int -> ST s (MVector s a)
start i
| i == V.length v ||
e <= v V.! i = MV.write mv i e >> finish i
| otherwise = MV.write mv i (v V.! i) >> start (i+1)
finish :: Int -> ST s (MVector s a)
finish i
| i == V.length v = return mv
| otherwise = do
V.indexM v i >>= MV.write mv (i+1)
finish (i+1)
in start 0
insertElemInt :: Int -> Vector Int -> Vector Int
insertElemInt = insertElem
, act ScopedTypeVariables , .
, . . , - , , . , , , , . , (), . , . , , .
testEnum :: Word -> Word -> Word -> Word
testEnum ins low high = V.product $
insertElem ins $ V.enumFromStepN low 1 (fromIntegral high)
, , .
{-
module Insert where
import Data.Vector (Vector)
import Data.Word (Word)
import qualified Data.Vector.Fusion.Stream.Monadic as S
import qualified Data.Vector.Generic as G
import Data.Vector.Fusion.Util (Id(..))
-- To check on unboxing and such
insertElemWord :: Word -> Vector Word -> Vector Word
insertElemWord = insertElem
{-
insertElem :: forall a . Ord a => a -> Vector a -> Vector a
insertElem a v = G.unstream (insertElemS a (G.stream v))
{-
insertElemS :: forall a . Ord a => a -> S.Stream Id a -> S.Stream Id a
insertElemS e (S.Stream step (state::s) size) = S.Stream step' (state, False) (size + 1)
where
{-# INLINE [0] step'
step' :: (s, Bool) -> Id (S.Step (s, Bool) a)
step' (s, True) = Id $ case unId (step s) of
S.Yield a s' -> S.Yield a (s', True)
S.Skip s' -> S.Skip (s', True)
S.Done -> S.Done
step' (s, False) = Id $ case unId (step s) of
S.Yield a s' ->
if e <= a
then S.Yield e (s, True)
else S.Yield a (s', False)
S.Skip s' -> S.Skip (s', False)
S.Done -> S.Yield e (s, True)
, /
{-
module Insert where
import Data.Vector (Vector)
import Data.Word (Word)
import qualified Data.Vector.Fusion.Stream.Monadic as S
import qualified Data.Vector.Generic as G
import Data.Vector.Fusion.Util (Id(..))
data Status s a = Pre s | During s a | Post s | End
insertElemWord :: Word -> Vector Word -> Vector Word
insertElemWord = insertElem
{-
insertElem :: forall a . Ord a => a -> Vector a -> Vector a
insertElem a v = G.unstream (insertElemS a (G.stream v))
{-
insertElemS :: forall a . Ord a => a -> S.Stream Id a -> S.Stream Id a
insertElemS e (S.Stream step (state::s) size) = S.Stream step' (Pre state) (size+1)
where
{-# INLINE [0] step'
step' :: Status s a -> Id (S.Step (Status s a) a)
step' (Post s) = Id $ case unId (step s) of
S.Yield a s' -> S.Yield a (Post s')
S.Skip s' -> S.Skip (Post s')
S.Done -> S.Done
step' (Pre s) = Id $ case unId (step s) of
S.Yield a s'
| e <= a -> S.Yield e (During s' a)
| otherwise -> S.Yield a (Pre s')
S.Skip s' -> S.Skip (Pre s')
S.Done -> S.Yield e End
step' (During s a) = Id (S.Yield a (Post s))
step' End = Id S.Done