on master help sign in
Fix lastN for n <= 0
59509cdadithyaov
src/Streamly/Internal/Data/Stream/StreamD.hs+15−13
@@ -4136,19 +4136,21 @@ tapAsync f (Stream step1 state1) = Stream step TapInit
4136-- | Take last 'n' elements from the stream and discard the rest.
4136-- | Take last 'n' elements from the stream and discard the rest.
4137{-# INLINE lastN #-}
4137{-# INLINE lastN #-}
4138lastN :: (Storable a, MonadIO m) => Int -> Fold m a (Array a)
4138lastN :: (Storable a, MonadIO m) => Int -> Fold m a (Array a)
4139+lastN n
4140+ | n <= 0 = fmap (const mempty) FL.drain
4139−lastN n = Fold step initial done
4141+ | otherwise = Fold step initial done
4140− where
4142+ where
4141− step (Tuple3' rb rh i) a = do
4143+ step (Tuple3' rb rh i) a = do
4142− rh1 <- liftIO $ RB.unsafeInsert rb rh a
4144+ rh1 <- liftIO $ RB.unsafeInsert rb rh a
4143− return $ Tuple3' rb rh1 (i + 1)
4145+ return $ Tuple3' rb rh1 (i + 1)
4144− initial = fmap (\(a, b) -> Tuple3' a b (0 :: Int)) $ liftIO $ RB.new n
4146+ initial = fmap (\(a, b) -> Tuple3' a b (0 :: Int)) $ liftIO $ RB.new n
4145− done (Tuple3' rb rh i) = do
4147+ done (Tuple3' rb rh i) = do
4146− arr <- liftIO $ A.newArray n
4148+ arr <- liftIO $ A.newArray n
4147− foldFunc i rh snoc' arr rb
4149+ foldFunc i rh snoc' arr rb
4148− snoc' b a = liftIO $ A.unsafeSnoc b a
4150+ snoc' b a = liftIO $ A.unsafeSnoc b a
4149− foldFunc i
4151+ foldFunc i
4150− | i < n = RB.unsafeFoldRingM
4152+ | i < n = RB.unsafeFoldRingM
4151− | otherwise = RB.unsafeFoldRingFullM
4153+ | otherwise = RB.unsafeFoldRingFullM
4152
4154
4153------------------------------------------------------------------------------
4155------------------------------------------------------------------------------
4154-- Time related
4156-- Time related
test/Streamly/Test/Array.hs+19−1
@@ -149,6 +149,22 @@ testLastN =
149 $ S.fold (A.lastN n)
149 $ S.fold (A.lastN n)
150 $ S.fromList list
150 $ S.fromList list
151 assert (xs == lastN n list)
151 assert (xs == lastN n list)
152+
153+testLastNLT :: Property
154+testLastNLT =
155+ forAll (choose (0, maxArrLen)) $ \len ->
156+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
157+ monadicIO $ do
158+ xs <- fmap A.toList $ S.fold (A.lastN 0) $ S.fromList list
159+ assert (xs == lastN 0 list)
160+
161+testLastNGT :: Property
162+testLastNGT =
163+ forAll (choose (0, maxArrLen)) $ \len ->
164+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
165+ monadicIO $ do
166+ xs <- fmap A.toList $ S.fold (A.lastN (len + 1)) $ S.fromList list
167+ assert (xs == lastN (len + 1) list)
152#endif
168#endif
153
169
154main :: IO ()
170main :: IO ()
@@ -174,5 +190,7 @@ main =
174#endif
190#endif
175#ifdef TEST_ARRAY
191#ifdef TEST_ARRAY
176 describe "Fold" $ do
192 describe "Fold" $ do
177− prop "lastN" $ testLastN
193+ prop "lastN : 0 <= n < len" $ testLastN
194+ prop "lastN : n = 0" $ testLastNLT
195+ prop "lastN : n = len + 1" $ testLastNGT
178#endif
196#endif