@@ -572,11 +572,16 @@ async = joinStreamVarAsync AsyncVar
572572(<|) :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
573573(<|) = async
574574
575+-- IMPORTANT: using a monomorphically typed and SPECIALIZED consMAsync makes a
576+-- huge difference in the performance of consM in IsStream instance even we
577+-- have a SPECIALIZE in the instance.
578+--
575579-- | XXX we can implement it more efficienty by directly implementing instead
576580-- of combining streams using async.
577581{-# INLINE consMAsync #-}
578−consMAsync :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
579−consMAsync m r = K.yieldM m `async` r
582+{-# SPECIALIZE consMAsync :: IO a -> AsyncT IO a -> AsyncT IO a #-}
583+consMAsync :: MonadAsync m => m a -> AsyncT m a -> AsyncT m a
584+consMAsync m r = fromStream $ K.yieldM m `async` (toStream r)
580585
581586------------------------------------------------------------------------------
582587-- AsyncT
@@ -649,21 +654,22 @@ asyncly = adapt
649654instance IsStream AsyncT where
650655 toStream = getAsyncT
651656 fromStream = AsyncT
652−
653− {-# INLINE consM #-}
654− {-# SPECIALIZE consM :: IO a -> AsyncT IO a -> AsyncT IO a #-}
655657 consM = consMAsync
656−
657− {-# INLINE (|:) #-}
658− {-# SPECIALIZE (|:) :: IO a -> AsyncT IO a -> AsyncT IO a #-}
659− (|:) = consM
658+ (|:) = consMAsync
660659
661660------------------------------------------------------------------------------
662661-- Semigroup
663662------------------------------------------------------------------------------
664663
664+-- Monomorphically typed version of "async" for better performance of Semigroup
665+-- instance.
666+{-# INLINE mappendAsync #-}
667+{-# SPECIALIZE mappendAsync :: AsyncT IO a -> AsyncT IO a -> AsyncT IO a #-}
668+mappendAsync :: MonadAsync m => AsyncT m a -> AsyncT m a -> AsyncT m a
669+mappendAsync m1 m2 = fromStream $ async (toStream m1) (toStream m2)
670+
665671instance MonadAsync m => Semigroup (AsyncT m a) where
666− (<>) = async
672+ (<>) = mappendAsync
667673
668674------------------------------------------------------------------------------
669675-- Monoid
@@ -677,14 +683,21 @@ instance MonadAsync m => Monoid (AsyncT m a) where
677683-- Monad
678684------------------------------------------------------------------------------
679685
686+{-# INLINE bindAsync #-}
687+{-# SPECIALIZE bindAsync :: AsyncT IO a -> (a -> AsyncT IO b) -> AsyncT IO b #-}
688+bindAsync :: MonadAsync m => AsyncT m a -> (a -> AsyncT m b) -> AsyncT m b
689+bindAsync m f = fromStream $ K.bindWith async (adapt m) (\a -> adapt $ f a)
690+
680691instance MonadAsync m => Monad (AsyncT m) where
681692 return = pure
682− (>>=) = K.bindWith async
693+ (>>=) = bindAsync
683694
684695------------------------------------------------------------------------------
685696-- Other instances
686697------------------------------------------------------------------------------
687698
699+-- XXX SPECIALIZE the applicative as well?
700+
688701MONAD_APPLICATIVE_INSTANCE(AsyncT,MONADPARALLEL)
689702MONAD_COMMON_INSTANCES(AsyncT, MONADPARALLEL)
690703
@@ -695,8 +708,9 @@ MONAD_COMMON_INSTANCES(AsyncT, MONADPARALLEL)
695708-- | XXX we can implement it more efficienty by directly implementing instead
696709-- of combining streams using wAsync.
697710{-# INLINE consMWAsync #-}
698−consMWAsync :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
699−consMWAsync m r = K.yieldM m `wAsync` r
711+{-# SPECIALIZE consMWAsync :: IO a -> WAsyncT IO a -> WAsyncT IO a #-}
712+consMWAsync :: MonadAsync m => m a -> WAsyncT m a -> WAsyncT m a
713+consMWAsync m r = fromStream $ K.yieldM m `wAsync` (toStream r)
700714
701715-- | Polymorphic version of the 'Semigroup' operation '<>' of 'WAsyncT'.
702716-- Merges two streams concurrently choosing elements from both fairly.
@@ -771,21 +785,20 @@ wAsyncly = adapt
771785instance IsStream WAsyncT where
772786 toStream = getWAsyncT
773787 fromStream = WAsyncT
774−
775− {-# INLINE consM #-}
776− {-# SPECIALIZE consM :: IO a -> WAsyncT IO a -> WAsyncT IO a #-}
777788 consM = consMWAsync
778−
779− {-# INLINE (|:) #-}
780− {-# SPECIALIZE (|:) :: IO a -> WAsyncT IO a -> WAsyncT IO a #-}
781− (|:) = consM
789+ (|:) = consMWAsync
782790
783791------------------------------------------------------------------------------
784792-- Semigroup
785793------------------------------------------------------------------------------
786794
795+{-# INLINE mappendWAsync #-}
796+{-# SPECIALIZE mappendWAsync :: WAsyncT IO a -> WAsyncT IO a -> WAsyncT IO a #-}
797+mappendWAsync :: MonadAsync m => WAsyncT m a -> WAsyncT m a -> WAsyncT m a
798+mappendWAsync m1 m2 = fromStream $ wAsync (toStream m1) (toStream m2)
799+
787800instance MonadAsync m => Semigroup (WAsyncT m a) where
788− (<>) = wAsync
801+ (<>) = mappendWAsync
789802
790803------------------------------------------------------------------------------
791804-- Monoid
@@ -799,9 +812,16 @@ instance MonadAsync m => Monoid (WAsyncT m a) where
799812-- Monad
800813------------------------------------------------------------------------------
801814
815+{-# INLINE bindWAsync #-}
816+{-# SPECIALIZE bindWAsync :: WAsyncT IO a -> (a -> WAsyncT IO b) -> WAsyncT IO b #-}
817+bindWAsync :: MonadAsync m => WAsyncT m a -> (a -> WAsyncT m b) -> WAsyncT m b
818+bindWAsync m f = fromStream $ K.bindWith wAsync (adapt m) (\a -> adapt $ f a)
819+
802820instance MonadAsync m => Monad (WAsyncT m) where
803821 return = pure
804− (>>=) = K.bindWith wAsync
822+ (>>=) = bindWAsync
823+
824+-- XXX SPECIALIZE the applicative as well?
805825
806826------------------------------------------------------------------------------
807827-- Other instances