{-# LANGUAGE TypeFamilies #-} {-# OPTIONS_GHC -Wall #-} -- | A 'RingBuffer' based on 'Data.Sequence.Seq'. Asymptotic behavior is quite -- good in all cases, but constant factors are very high. module Data.RingBuffer.SeqBuffer ( SeqBuffer ,RingBuffer (..) ,new ) where import Prelude hiding (length, (!!)) import Data.RingBuffer.Class import qualified Data.Sequence as S import Data.Foldable newtype SeqBuffer a = RB (S.Seq a) deriving (Eq, Ord, Show) type instance El (SeqBuffer a) = a instance Initializable (SeqBuffer a) where {-# INLINE newInit #-} newInit = newInit' instance RingBuffer (SeqBuffer a) where {-# INLINE length #-} length = length' {-# INLINE push #-} push = push' {-# INLINE (!) #-} (!) = (!!) {-# INLINE slice #-} slice (RB sq) start num = toList . S.take num $ S.drop start sq -- | Create a new SeqBuffer, initialized to all 0's, of the given size new :: (Num a) => Int -> SeqBuffer a new = newInit' 0 {-# INLINE new #-} -- | Create a new SeqBuffer from a given initial value newInit' :: a -> Int -> SeqBuffer a newInit' _ sz | sz <= 0 = error "can't make empty ringbuffer" newInit' i sz = RB (S.replicate sz i) {-# INLINE newInit' #-} -- | Get the total size of a SeqBuffer. length' :: SeqBuffer a -> Int length' (RB vec) = S.length vec {-# INLINE length' #-} -- | Look up a value in a SeqBuffer. (!!) :: SeqBuffer a -> Int -> a (!!) (RB vec) = S.index vec {-# INLINE (!!) #-} -- | Push a new value into a SeqBuffer. The following will hold: -- NewSeqBuffer ! 0 === added element -- NewSeqBuffer ! 1 === OldSeqBuffer ! 0 push' :: SeqBuffer a -> a -> SeqBuffer a push' (RB vec) el = case S.viewr vec of v' S.:> _ -> RB $ el S.<| v' _ -> error "internal error" {-# INLINE push' #-}