@@ -356,6 +356,9 @@ module Streamly.Internal.Data.Fold.Type
356356 , filter
357357 , filterM
358358 , catMaybes
359+ , lefts
360+ , rights
361+ , both
359362
360363 -- ** Trimming
361364 , take
@@ -396,6 +399,7 @@ where
396399#include "inline.hs"
397400import Control.Monad ((>=>))
398401import Data.Bifunctor (Bifunctor(..))
402+import Data.Either (fromLeft, fromRight, isLeft, isRight)
399403import Data.Maybe (isJust, fromJust)
400404import Fusion.Plugin.Types (Fuse(..))
401405import Streamly.Internal.Data.Fold.Step (Step(..), mapMStep, chainStepM)
@@ -1172,6 +1176,35 @@ filterM f (Fold step begin done) = Fold step' begin done
11721176catMaybes :: Monad m => Fold m a b -> Fold m (Maybe a) b
11731177catMaybes = filter isJust . lmap fromJust
11741178
1179+------------------------------------------------------------------------------
1180+-- Either streams
1181+------------------------------------------------------------------------------
1182+
1183+-- | Discard 'Right's and unwrap 'Left's in an 'Either' stream.
1184+--
1185+-- /Pre-release/
1186+--
1187+{-# INLINE lefts #-}
1188+lefts :: (Monad m) => Fold m a c -> Fold m (Either a b) c
1189+lefts = filter isLeft . lmap (fromLeft undefined)
1190+
1191+-- | Discard 'Left's and unwrap 'Right's in an 'Either' stream.
1192+--
1193+-- /Pre-release/
1194+--
1195+{-# INLINE rights #-}
1196+rights :: (Monad m) => Fold m b c -> Fold m (Either a b) c
1197+rights = filter isRight . lmap (fromRight undefined)
1198+
1199+-- | Remove the either wrapper and flatten both lefts and as well as rights in
1200+-- the output stream.
1201+--
1202+-- /Pre-release/
1203+--
1204+{-# INLINE both #-}
1205+both :: Fold m a b -> Fold m (Either a a) b
1206+both = lmap (either id id)
1207+
11751208------------------------------------------------------------------------------
11761209-- Parsing
11771210------------------------------------------------------------------------------