on 43dda21 help sign in
157 lines 3.8 kB history raw
1-- |
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
7-- Portability : GHC
8--
9-- A newtype wrapper over the 'Fold' type providing distributing 'Applicative',
10-- 'Semigroup', 'Monoid', 'Num', 'Floating' and 'Fractional' instances.
11--
12module Streamly.Internal.Data.Fold.Tee
13 ( Tee(..)
14 )
15where
17import Control.Applicative (liftA2)
18#if __GLASGOW_HASKELL__ < 808
19import Data.Semigroup (Semigroup(..))
20#endif
21import Streamly.Internal.Data.Fold.Type (Fold)
23import qualified Streamly.Internal.Data.Fold.Type as Fold
25-- | @Tee@ is a newtype wrapper over the 'Fold' type providing distributing
26-- 'Applicative', 'Semigroup', 'Monoid', 'Num', 'Floating' and 'Fractional'
27-- instances.
28--
29-- @since 0.8.0
30newtype Tee m a b =
31 Tee { toFold :: Fold m a b }
32 deriving (Functor)
34-- | '<*>' distributes the input to both the argument 'Tee's and combines their
35-- outputs using function application.
36--
37instance Monad m => Applicative (Tee m a) where
39 {-# INLINE pure #-}
40 pure a = Tee (Fold.fromPure a)
42 {-# INLINE (<*>) #-}
43 (<*>) a b = Tee (Fold.teeWith ($) (toFold a) (toFold b))
45-- | '<>' distributes the input to both the argument 'Tee's and combines their
46-- outputs using the 'Semigroup' instance of the output type.
47--
48instance (Semigroup b, Monad m) => Semigroup (Tee m a b) where
49 {-# INLINE (<>) #-}
50 (<>) = liftA2 (<>)
52-- | '<>' distributes the input to both the argument 'Tee's and combines their
53-- outputs using the 'Monoid' instance of the output type.
54--
55instance (Semigroup b, Monoid b, Monad m) => Monoid (Tee m a b) where
56 {-# INLINE mempty #-}
57 mempty = pure mempty
59 {-# INLINE mappend #-}
60 mappend = (<>)
62-- | Binary 'Num' operations distribute the input to both the argument 'Tee's
63-- and combine their outputs using the 'Num' instance of the output type.
64--
65instance (Monad m, Num b) => Num (Tee m a b) where
66 {-# INLINE fromInteger #-}
67 fromInteger = pure . fromInteger
69 {-# INLINE negate #-}
70 negate = fmap negate
72 {-# INLINE abs #-}
73 abs = fmap abs
75 {-# INLINE signum #-}
76 signum = fmap signum
78 {-# INLINE (+) #-}
79 (+) = liftA2 (+)
81 {-# INLINE (*) #-}
82 (*) = liftA2 (*)
84 {-# INLINE (-) #-}
85 (-) = liftA2 (-)
87-- | Binary 'Fractional' operations distribute the input to both the argument
88-- 'Tee's and combine their outputs using the 'Fractional' instance of the
89-- output type.
90--
91instance (Monad m, Fractional b) => Fractional (Tee m a b) where
92 {-# INLINE fromRational #-}
93 fromRational = pure . fromRational
95 {-# INLINE recip #-}
96 recip = fmap recip
98 {-# INLINE (/) #-}
99 (/) = liftA2 (/)
101-- | Binary 'Floating' operations distribute the input to both the argument
102-- 'Tee's and combine their outputs using the 'Floating' instance of the output
103-- type.
104instance (Monad m, Floating b) => Floating (Tee m a b) where
105 {-# INLINE pi #-}
106 pi = pure pi
108 {-# INLINE exp #-}
109 exp = fmap exp
111 {-# INLINE sqrt #-}
112 sqrt = fmap sqrt
114 {-# INLINE log #-}
115 log = fmap log
117 {-# INLINE sin #-}
118 sin = fmap sin
120 {-# INLINE tan #-}
121 tan = fmap tan
123 {-# INLINE cos #-}
124 cos = fmap cos
126 {-# INLINE asin #-}
127 asin = fmap asin
129 {-# INLINE atan #-}
130 atan = fmap atan
132 {-# INLINE acos #-}
133 acos = fmap acos
135 {-# INLINE sinh #-}
136 sinh = fmap sinh
138 {-# INLINE tanh #-}
139 tanh = fmap tanh
141 {-# INLINE cosh #-}
142 cosh = fmap cosh
144 {-# INLINE asinh #-}
145 asinh = fmap asinh
147 {-# INLINE atanh #-}
148 atanh = fmap atanh
150 {-# INLINE acosh #-}
151 acosh = fmap acosh
153 {-# INLINE (**) #-}
154 (**) = liftA2 (**)
156 {-# INLINE logBase #-}
157 logBase = liftA2 logBase