on master help sign in
Reduce polymorphic code in fromStreamVar
19b5a6fHarendra Kumar
src/Streamly/Internal/Data/Stream/SVar.hs+37−3
@@ -1,6 +1,15 @@
1{-# LANGUAGE CPP #-}
1{-# LANGUAGE CPP #-}
2{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
3
3
4+#ifdef __HADDOCK_VERSION__
5+#undef INSPECTION
6+#endif
7+
8+#ifdef INSPECTION
9+{-# LANGUAGE TemplateHaskell #-}
10+{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
11+#endif
12+
4-- |
13-- |
5-- Module : Streamly.Internal.Data.Stream.SVar
14-- Module : Streamly.Internal.Data.Stream.SVar
6-- Copyright : (c) 2017 Harendra Kumar
15-- Copyright : (c) 2017 Harendra Kumar
@@ -33,10 +42,18 @@ import System.Mem (performMajorGC)
33import Streamly.Internal.Data.SVar
42import Streamly.Internal.Data.SVar
34import Streamly.Internal.Data.Stream.StreamK hiding (reverse)
43import Streamly.Internal.Data.Stream.StreamK hiding (reverse)
35
44
45+#ifdef INSPECTION
46+import Control.Exception (Exception)
47+import Control.Monad.Catch (MonadThrow)
48+import Control.Monad.Trans.Control (MonadBaseControl)
49+import Data.Typeable (Typeable)
50+import Test.Inspection (inspect, hasNoTypeClassesExcept)
51+#endif
52+
36-- | Pull a stream from an SVar.
53-- | Pull a stream from an SVar.
37{-# NOINLINE fromStreamVar #-}
54{-# NOINLINE fromStreamVar #-}
38fromStreamVar :: MonadAsync m => SVar Stream m a -> Stream m a
55fromStreamVar :: MonadAsync m => SVar Stream m a -> Stream m a
39−fromStreamVar sv = mkStream $ \st yld sng stp -> do
56+fromStreamVar sv = MkStream $ \st yld sng stp -> do
40 list <- readOutputQ sv
57 list <- readOutputQ sv
41 -- Reversing the output is important to guarantee that we process the
58 -- Reversing the output is important to guarantee that we process the
42 -- outputs in the same order as they were generated by the constituent
59 -- outputs in the same order as they were generated by the constituent
@@ -53,13 +70,13 @@ fromStreamVar sv = mkStream $ \st yld sng stp -> do
53 stp
70 stp
54
71
55 {-# INLINE processEvents #-}
72 {-# INLINE processEvents #-}
56− processEvents [] = mkStream $ \st yld sng stp -> do
73+ processEvents [] = MkStream $ \st yld sng stp -> do
57 done <- postProcess sv
74 done <- postProcess sv
58 if done
75 if done
59 then allDone stp
76 then allDone stp
60 else foldStream st yld sng stp $ fromStreamVar sv
77 else foldStream st yld sng stp $ fromStreamVar sv
61
78
62− processEvents (ev : es) = mkStream $ \st yld sng stp -> do
79+ processEvents (ev : es) = MkStream $ \st yld sng stp -> do
63 let rest = processEvents es
80 let rest = processEvents es
64 case ev of
81 case ev of
65 ChildYield a -> yld a rest
82 ChildYield a -> yld a rest
@@ -84,6 +101,23 @@ fromStreamVar sv = mkStream $ \st yld sng stp -> do
84 sid <- liftIO $ readIORef (svarStopBy sv)
101 sid <- liftIO $ readIORef (svarStopBy sv)
85 return $ if tid == sid then True else False
102 return $ if tid == sid then True else False
86
103
104+#ifdef INSPECTION
105+-- Use of GHC constraint tuple (GHC.Classes.(%,,%)) in fromStreamVar leads to
106+-- space leak because the tuple gets allocated in every recursive call and each
107+-- allocation holds on to the previous allocation. This test is to make sure
108+-- that we do not use the constraint tuple type class.
109+--
110+inspect $ hasNoTypeClassesExcept 'fromStreamVar
111+ [ ''Monad
112+ , ''Applicative
113+ , ''MonadThrow
114+ , ''Exception
115+ , ''MonadIO
116+ , ''MonadBaseControl
117+ , ''Typeable
118+ ]
119+#endif
120+
87{-# INLINE fromSVar #-}
121{-# INLINE fromSVar #-}
88fromSVar :: (MonadAsync m, IsStream t) => SVar Stream m a -> t m a
122fromSVar :: (MonadAsync m, IsStream t) => SVar Stream m a -> t m a
89fromSVar sv =
123fromSVar sv =
src/Streamly/Internal/Data/Stream/StreamK.hs+1−1
@@ -35,7 +35,7 @@ module Streamly.Internal.Data.Stream.StreamK
35 , adapt
35 , adapt
36
36
37 -- * The stream type
37 -- * The stream type
38− , Stream
38+ , Stream(..)
39
39
40 -- * Construction Primitives
40 -- * Construction Primitives
41 , mkStream
41 , mkStream
src/Streamly/Internal/Data/Stream/StreamK/Type.hs+1−1
@@ -36,7 +36,7 @@ module Streamly.Internal.Data.Stream.StreamK.Type
36 , adapt
36 , adapt
37
37
38 -- * The stream type
38 -- * The stream type
39− , Stream ()
39+ , Stream (..)
40
40
41 -- * Construction
41 -- * Construction
42 , mkStream
42 , mkStream
streamly.cabal+6−2
@@ -385,10 +385,14 @@ library
385
385
386 if !impl(ghcjs)
386 if !impl(ghcjs)
387 build-depends:
387 build-depends:
388− network >= 2.6 && < 4
388+ network >= 2.6 && < 4
389 if impl(ghc < 8.0)
389 if impl(ghc < 8.0)
390 build-depends:
390 build-depends:
391− semigroups >= 0.18 && < 0.19
391+ semigroups >= 0.18 && < 0.19
392+
393+ if flag(inspection)
394+ build-depends: template-haskell >= 2.14 && < 2.16
395+ , inspection-testing >= 0.4 && < 0.5
392
396
393 -- Array uses a Storable constraint in dev build making several inspection
397 -- Array uses a Storable constraint in dev build making several inspection
394 -- tests fail
398 -- tests fail