@@ -0,0 +1,51 @@
2+-- Module : Streamly.Internal.Data.Fold.Tee
3+-- Copyright : (c) 2020 Composewell Technologies
4+-- License : BSD-3-Clause
5+-- Maintainer : streamly@composewell.com
6+-- Stability : experimental
9+module Streamly.Internal.Data.Fold.Tee
16+import Data.Coerce (coerce)
17+import Streamly.Internal.Data.Fold.Types (Fold)
19+import qualified Streamly.Internal.Data.Fold.Types as Fold
21+-- | The type @Tee m a b@ represents a left fold over an input stream of values
22+-- of type @a@ to a single value of type @b@ in 'Monad' @m@.
24+-- @Tee@ is a wrapper over 'Fold' that uses 'teeWith' to define the applicative
29+ Tee { runTee :: Fold m a b }
32+-- | Convert a 'Tee' to 'Fold'.
34+toFold :: Tee m a b -> Fold m a b
37+-- | Convert a 'Fold' to 'Tee'.
38+{-# INLINE fromFold #-}
39+fromFold :: Fold m a b -> Tee m a b
42+-- | The 'Tee' resulting from '<*>' distributes its input to both the argument
43+-- 'Tee's and combines their output using function application.
45+instance Monad m => Applicative (Tee m a) where
48+ pure a = fromFold (Fold.yield a)
51+ (<*>) a b = fromFold (Fold.teeWith ($) (toFold a) (toFold b))