module VectorBuilder.Private.Action where import VectorBuilder.Private.Prelude import qualified Data.Vector.Mutable as A import qualified Data.Vector as B newtype Action s element result = Action (Int -> (A.MVector s element -> ST s result, Int)) instance Functor (Action s element) where fmap fn (Action actionFn) = Action $ \size -> case actionFn size of (updateFn, newSize) -> (fmap fn . updateFn, newSize) instance Applicative (Action s element) where pure result = Action (\size -> (const (pure result), size)) (<*>) (Action actionFn1) (Action actionFn2) = Action actionFn where actionFn size = case actionFn1 size of (vectorFn1, size1) -> case actionFn2 size1 of (vectorFn2, size2) -> ((<*>) <$> vectorFn1 <*> vectorFn2, size2) snoc :: element -> Action s element () snoc element = Action (\size -> (\mVector -> A.unsafeWrite mVector size element, succ size)) append :: B.Vector element -> Action s element () append appendedVector = Action ((,) <$> vectorFn <*> size) where vectorFn currentSize mVector = B.ifoldM' (\_ index element -> A.unsafeWrite mVector (currentSize + index) element) () appendedVector size currentSize = B.length appendedVector + currentSize