@@ -280,6 +280,7 @@ module Streamly.Internal.Data.Fold
280280 , finish
281281 , top
282282 , bottom
283+ , nub
283284
284285 -- * Deprecated
285286 , sequence
@@ -335,7 +336,7 @@ import Streamly.Internal.Data.Fold.Type
335336-- >>> :set -package streamly
336337-- >>> import Prelude hiding (break, map, span, splitAt)
337338-- >>> import qualified Streamly.Prelude as Stream
338−-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse, foldMany)
339+-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (catMaybes, parse, foldMany)
339340-- >>> import qualified Streamly.Data.Fold as Fold
340341-- >>> import qualified Streamly.Internal.Data.Fold as Fold
341342-- >>> import qualified Streamly.Internal.Data.Fold.Type as Fold
@@ -2562,3 +2563,26 @@ top = topBy $ flip compare
25622563{-# INLINE bottom #-}
25632564bottom :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (MA.Array a)
25642565bottom = topBy compare
2566+
2567+-- | Delete the duplicate elements from the stream while scanning.
2568+-- It returns (Just a) for new element and Nothing for duplicates ones.
2569+--
2570+-- >>> stream = Stream.fromList [1::Int, 1, 2, 3, 4, 4, 5, 1, 5, 7]
2571+-- >>> Stream.toList $ Stream.catMaybes $ Stream.postscan Fold.nub stream
2572+-- [1,2,3,4,5,7]
2573+--
2574+-- /Pre-release/
2575+{-# INLINE nub #-}
2576+nub :: (MonadIO m, Ord a) => Fold m a (Maybe a)
2577+nub = Fold step initial extract
2578+
2579+ where
2580+
2581+ initial = return $ Partial (Set.empty, Nothing)
2582+
2583+ step (set, _) x = do
2584+ if Set.member x set
2585+ then return $ Partial (set, Nothing)
2586+ else return $ Partial (Set.insert x set, Just x)
2587+
2588+ extract = return . snd