@@ -135,7 +135,7 @@ module Streamly.Internal.Data.Array.Storable.Foreign
137 -- * Folds with Array as the container
137 -- * Folds with Array as the container
138− , D.lastN
138+ , lastN
@@ -157,17 +157,21 @@ import GHC.Ptr (Ptr(..))
157import GHC.Prim (touch#)
157import GHC.Prim (touch#)
158import GHC.IO (IO(..))
158import GHC.IO (IO(..))
160−import Streamly.Internal.Data.Fold.Types (Fold(..))
161−import Streamly.Internal.Data.Unfold.Types (Unfold(..))
162import Streamly.Internal.Data.Array.Storable.Foreign.Types (Array(..), length)
160import Streamly.Internal.Data.Array.Storable.Foreign.Types (Array(..), length)
161+import Streamly.Internal.Data.Fold.Types (Fold(..))
163import Streamly.Internal.Data.Stream.Serial (SerialT)
162import Streamly.Internal.Data.Stream.Serial (SerialT)
164import Streamly.Internal.Data.Stream.StreamK.Type (IsStream)
163import Streamly.Internal.Data.Stream.StreamK.Type (IsStream)
164+import Streamly.Internal.Data.Tuple.Strict (Tuple3'(..))
165+import Streamly.Internal.Data.Unfold.Types (Unfold(..))
167+import qualified Streamly.Internal.Data.Array.Storable.Foreign.Mut.Types as MA
166import qualified Streamly.Internal.Data.Array.Storable.Foreign.Types as A
168import qualified Streamly.Internal.Data.Array.Storable.Foreign.Types as A
169+import qualified Streamly.Internal.Data.Fold as FL
167import qualified Streamly.Internal.Data.Stream.Prelude as P
170import qualified Streamly.Internal.Data.Stream.Prelude as P
168import qualified Streamly.Internal.Data.Stream.Serial as Serial
171import qualified Streamly.Internal.Data.Stream.Serial as Serial
169import qualified Streamly.Internal.Data.Stream.StreamD as D
172import qualified Streamly.Internal.Data.Stream.StreamD as D
170import qualified Streamly.Internal.Data.Stream.StreamK as K
173import qualified Streamly.Internal.Data.Stream.StreamK as K
174+import qualified Streamly.Memory.Ring as RB
172-------------------------------------------------------------------------------
176-------------------------------------------------------------------------------
173-- Construction
177-- Construction
@@ -301,6 +305,29 @@ null arr = length arr == 0
301last :: Storable a => Array a -> Maybe a
305last :: Storable a => Array a -> Maybe a
302last arr = readIndex arr (length arr - 1)
306last arr = readIndex arr (length arr - 1)
308+-------------------------------------------------------------------------------
309+-- Folds with Array as the container
310+-------------------------------------------------------------------------------
312+-- | Take last 'n' elements from the stream and discard the rest.
314+lastN :: (Storable a, MonadIO m) => Int -> Fold m a (Array a)
316+ | n <= 0 = fmap (const mempty) FL.drain
317+ | otherwise = A.unsafeFreeze <$> Fold step initial done
319+ step (Tuple3' rb rh i) a = do
320+ rh1 <- liftIO $ RB.unsafeInsert rb rh a
321+ return $ FL.Partial $ Tuple3' rb rh1 (i + 1)
322+ initial = fmap (\(a, b) -> Tuple3' a b (0 :: Int)) $ liftIO $ RB.new n
323+ done (Tuple3' rb rh i) = do
324+ arr <- liftIO $ MA.newArray n
325+ foldFunc i rh snoc' arr rb
326+ snoc' b a = liftIO $ MA.unsafeSnoc b a
328+ | i < n = RB.unsafeFoldRingM
329+ | otherwise = RB.unsafeFoldRingFullM
304-------------------------------------------------------------------------------
331-------------------------------------------------------------------------------
305-- Random Access
332-- Random Access
306-------------------------------------------------------------------------------
333-------------------------------------------------------------------------------