Skip to content

Commit 3fe8ea1

Browse files
committed
move ListT into its own module, fix a bunch of reinventing the wheel instances
1 parent 21ca6d4 commit 3fe8ea1

File tree

3 files changed

+162
-183
lines changed

3 files changed

+162
-183
lines changed

src/Streaming/ListT.hs

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
{-# LANGUAGE FlexibleInstances #-}
2+
{-# LANGUAGE MultiParamTypeClasses #-}
3+
{-# LANGUAGE UndecidableInstances #-}
4+
5+
{-# OPTIONS_GHC -Wall #-}
6+
7+
module Streaming.ListT
8+
( ListT(..)
9+
--, runListT
10+
) where
11+
12+
import Streaming.Internal
13+
import Data.Functor.Of
14+
import qualified Streaming.Prelude as S
15+
16+
import Control.Applicative (Applicative (..)) --, Alternative (..))
17+
import Control.Monad.IO.Class (MonadIO (liftIO))
18+
import Control.Monad.Morph
19+
import Control.Monad.Error.Class
20+
import Control.Monad.Reader.Class
21+
import Control.Monad.State.Class
22+
import Control.Monad.Writer.Class
23+
import Control.Monad.Zip
24+
import Data.Functor (Functor (..))
25+
--import Data.Semigroup (Semigroup ((<>)))
26+
27+
newtype ListT m a = Select { enumerate :: Stream (Of a) m () }
28+
29+
instance Monad m => Functor (ListT m) where
30+
fmap f (Select p) = Select (S.map f p)
31+
{-# INLINE fmap #-}
32+
33+
instance Monad m => Applicative (ListT m) where
34+
pure a = Select (S.yield a)
35+
{-# INLINE pure #-}
36+
mf <*> mx = Select
37+
( S.for (enumerate mf) (\f ->
38+
S.for (enumerate mx) (\x ->
39+
S.yield (f x)))
40+
)
41+
42+
instance Monad m => Monad (ListT m) where
43+
return = pure
44+
{-# INLINE return #-}
45+
m >>= f = Select (S.for (enumerate m) (\a -> enumerate (f a)))
46+
{-# INLINE (>>=) #-}
47+
48+
instance (Monad m, Foldable m) => Foldable (ListT m) where
49+
foldMap f (Select p) = foldMap id (S.foldMap_ f p)
50+
51+
instance (Monad m, Traversable m) => Traversable (ListT m) where
52+
traverse k (Select p) = fmap Select (t_ p)
53+
where
54+
t_ x = case x of
55+
Return () -> pure (Return ())
56+
Effect m -> fmap Effect (traverse t_ m)
57+
Step (a :> rest) -> (\a_ rest_ -> Step (a_ :> rest_)) <$> k a <*> t_ rest
58+
59+
instance MonadTrans ListT where
60+
lift m = Select (do
61+
a <- lift m
62+
S.yield a)
63+
64+
instance MonadIO m => MonadIO (ListT m) where
65+
liftIO m = lift (liftIO m)
66+
{-# INLINE liftIO #-}
67+
68+
-- what should this be?
69+
--instance Monad m => Alternative (ListT m) where
70+
71+
--instance Monad m => MonadPlus (ListT m) where
72+
-- mzero = empty
73+
-- {-# INLINE mzero #-}
74+
-- mplus = (<|>)
75+
-- {-# INLINE mplus #-}
76+
77+
instance MFunctor ListT where
78+
hoist morph = Select . hoist morph . enumerate
79+
{-# INLINE hoist #-}
80+
81+
instance MMonad ListT where
82+
embed f (Select p0) = Select (loop p0)
83+
where
84+
loop x = case x of
85+
Return () -> Return ()
86+
Effect m -> S.for (enumerate (fmap loop (f m))) id
87+
Step (a :> rest) -> Step (a :> loop rest)
88+
{-# INLINE embed #-}
89+
90+
instance (MonadState s m) => MonadState s (ListT m) where
91+
get = lift get
92+
{-# INLINE get #-}
93+
94+
put s = lift (put s)
95+
{-# INLINE put #-}
96+
97+
state f = lift (state f)
98+
{-# INLINE state #-}
99+
100+
instance (MonadWriter w m) => MonadWriter w (ListT m) where
101+
writer = lift . writer
102+
{-# INLINE writer #-}
103+
104+
tell w = lift (tell w)
105+
{-# INLINE tell #-}
106+
107+
listen l = Select (go (enumerate l) mempty)
108+
where
109+
go p w = case p of
110+
Return () -> Return ()
111+
Effect m -> Effect (do
112+
(p', w') <- listen m
113+
pure (go p' $! mappend w w') )
114+
Step (a :> rest) -> Step ((a,w) :> go rest w)
115+
116+
pass l = Select (go (enumerate l) mempty)
117+
where
118+
go p w = case p of
119+
Return () -> Return ()
120+
Effect m -> Effect (do
121+
(p', w') <- listen m
122+
pure (go p' $! mappend w w'))
123+
Step ((b,f) :> rest) -> Effect (pass (pure
124+
(Step (b :> (go rest (f w))), \_ -> f w) ))
125+
126+
instance (MonadReader i m) => MonadReader i (ListT m) where
127+
ask = lift ask
128+
{-# INLINE ask #-}
129+
130+
local f l = Select (local f (enumerate l))
131+
{-# INLINE local #-}
132+
133+
reader f = lift (reader f)
134+
{-# INLINE reader #-}
135+
136+
instance (MonadError e m) => MonadError e (ListT m) where
137+
throwError e = lift (throwError e)
138+
{-# INLINE throwError #-}
139+
140+
catchError l k = Select (catchError (enumerate l) (\e -> enumerate (k e)))
141+
{-# INLINE catchError #-}
142+
143+
{- These instances require a dependency on `exceptions`.
144+
instance MonadThrow m => MonadThrow (ListT m) where
145+
throwM = Select . throwM
146+
{-# INLINE throwM #-}
147+
148+
instance MonadCatch m => MonadCatch (ListT m) where
149+
catch l k = Select (Control.Monad.Catch.catch (enumerate l) (\e -> enumerate (k e)))
150+
{-# INLINE catch #-}
151+
-}
152+
153+
instance Monad m => MonadZip (ListT m) where
154+
mzipWith f (Select p) (Select p') = Select (S.zipWith f p p')
155+
156+
-- no MonadPlus instance yet
157+
--runListT :: Monad m => ListT m a -> m ()
158+
--runListT l = S.effects (enumerate (l >> mzero))
159+
--{-# INLINABLE runListT #-}

src/Streaming/Prelude.hs

Lines changed: 2 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -258,26 +258,15 @@ module Streaming.Prelude (
258258

259259
-- * Basic Type
260260
, Stream
261-
262-
-- * ListT
263-
, ListT(..)
264-
, runListT
265261
) where
266262
import Streaming.Internal
267263

268264
import Control.Monad hiding (filterM, mapM, mapM_, foldM, foldM_, replicateM, sequence)
269265
import Data.Functor.Identity
270266
import Data.Functor.Sum
271267
import Control.Monad.Trans
272-
import Control.Applicative (Applicative (..), Alternative (..))
273-
import Control.Monad.Morph
274-
import Control.Monad.Error.Class
275-
import Control.Monad.Reader.Class
276-
import Control.Monad.State.Class
277-
import Control.Monad.Writer.Class
278-
import Control.Monad.Zip
268+
import Control.Applicative (Applicative (..))
279269
import Data.Functor (Functor (..), (<$))
280-
import Data.Semigroup (Semigroup ((<>)))
281270

282271
import qualified Prelude as Prelude
283272
import qualified Data.Foldable as Foldable
@@ -2934,174 +2923,4 @@ mapMaybeM phi = loop where
29342923
flip fmap (phi a) $ \x -> case x of
29352924
Nothing -> loop snext
29362925
Just b -> Step (b :> loop snext)
2937-
{-#INLINABLE mapMaybeM #-}
2938-
2939-
{-| The list monad transformer.
2940-
'pure' and 'return' correspond to 'yield', yielding a single value.
2941-
('>>=') corresponds to 'for', calling the second computation once for
2942-
each time the first computation 'yield's.
2943-
-}
2944-
newtype ListT m a = Select { enumerate :: Stream (Of a) m () }
2945-
2946-
instance Monad m => Functor (ListT m) where
2947-
fmap f p = Select (for (enumerate p) (\a -> yield (f a)))
2948-
{-# INLINE fmap #-}
2949-
2950-
instance Monad m => Applicative (ListT m) where
2951-
pure a = Select (yield a)
2952-
{-# INLINE pure #-}
2953-
mf <*> mx = Select (
2954-
for (enumerate mf) (\f ->
2955-
for (enumerate mx) (\x ->
2956-
yield (f x) ) ) )
2957-
2958-
instance Monad m => Monad (ListT m) where
2959-
return = pure
2960-
{-# INLINE return #-}
2961-
m >>= f = Select (for (enumerate m) (\a -> enumerate (f a)))
2962-
{-# INLINE (>>=) #-}
2963-
2964-
instance Foldable m => Foldable (ListT m) where
2965-
foldMap f = go . enumerate
2966-
where
2967-
go p = case p of
2968-
Return () -> mempty
2969-
Effect m -> Foldable.foldMap go m
2970-
Step (a :> rest) -> f a `mappend` go rest
2971-
{-# INLINE foldMap #-}
2972-
2973-
instance (Monad m, Traversable m) => Traversable (ListT m) where
2974-
traverse k (Select p) = fmap Select (traverse_ p)
2975-
where
2976-
traverse_ (Return ()) = pure (Return ())
2977-
traverse_ (Effect m) = fmap Effect (traverse traverse_ m)
2978-
traverse_ (Step (a :> rest)) = (\a_ rest_ -> Step (a_ :> rest_)) <$> k a <*> traverse_ rest
2979-
2980-
instance MonadTrans ListT where
2981-
lift m = Select (do
2982-
a <- lift m
2983-
yield a )
2984-
2985-
instance MonadIO m => MonadIO (ListT m) where
2986-
liftIO m = lift (liftIO m)
2987-
{-# INLINE liftIO #-}
2988-
2989-
instance Monad m => Alternative (ListT m) where
2990-
empty = Select (pure ())
2991-
{-# INLINE empty #-}
2992-
p1 <|> p2 = Select (do
2993-
enumerate p1
2994-
enumerate p2 )
2995-
2996-
instance Monad m => MonadPlus (ListT m) where
2997-
mzero = empty
2998-
{-# INLINE mzero #-}
2999-
mplus = (<|>)
3000-
{-# INLINE mplus #-}
3001-
3002-
instance MFunctor ListT where
3003-
hoist morph = Select . hoist morph . enumerate
3004-
{-# INLINE hoist #-}
3005-
3006-
instance MMonad ListT where
3007-
embed f (Select p0) = Select (loop p0)
3008-
where
3009-
loop (Return ()) = Return ()
3010-
loop (Effect m) = for (enumerate (fmap loop (f m))) id
3011-
loop (Step (a :> rest)) = Step (a :> loop rest)
3012-
{-# INLINE embed #-}
3013-
3014-
instance Monad m => Semigroup (ListT m a) where
3015-
(<>) = (<|>)
3016-
{-# INLINE (<>) #-}
3017-
3018-
instance Monad m => Monoid (ListT m a) where
3019-
mempty = empty
3020-
{-# INLINE mempty #-}
3021-
#if !(MIN_VERSION_base(4,11,0))
3022-
mappend = (<|>)
3023-
{-# INLINE mappend #-}
3024-
#endif
3025-
3026-
instance (MonadState s m) => MonadState s (ListT m) where
3027-
get = lift get
3028-
{-# INLINE get #-}
3029-
3030-
put s = lift (put s)
3031-
{-# INLINE put #-}
3032-
3033-
state f = lift (state f)
3034-
{-# INLINE state #-}
3035-
3036-
instance (MonadWriter w m) => MonadWriter w (ListT m) where
3037-
writer = lift . writer
3038-
{-# INLINE writer #-}
3039-
3040-
tell w = lift (tell w)
3041-
{-# INLINE tell #-}
3042-
3043-
--listen :: ListT m a -> ListT m (a, w)
3044-
listen l = Select (go (enumerate l) mempty)
3045-
where
3046-
go p w = case p of
3047-
Return () -> Return ()
3048-
Effect m -> Effect (do
3049-
(p', w') <- listen m
3050-
pure (go p' $! mappend w w') )
3051-
Step (a :> rest) -> Step ( (a,w) :> go rest w)
3052-
3053-
pass l = Select (go (enumerate l) mempty)
3054-
where
3055-
--go :: forall m a w. Stream (Of (w, a)) m () -> (w -> w) -> Stream (Of a) m ()
3056-
go p w = case p of
3057-
Return () -> Return ()
3058-
Effect m -> Effect (do
3059-
(p', w') <- listen m
3060-
pure (go p' $! mappend w w'))
3061-
Step ((b, f) :> rest) -> Effect (pass (return (Step (b :> (go rest (f w))), \_ -> f w) ))
3062-
3063-
instance (MonadReader i m) => MonadReader i (ListT m) where
3064-
ask = lift ask
3065-
{-# INLINE ask #-}
3066-
3067-
local f l = Select (local f (enumerate l))
3068-
{-# INLINE local #-}
3069-
3070-
reader f = lift (reader f)
3071-
{-# INLINE reader #-}
3072-
3073-
instance (MonadError e m) => MonadError e (ListT m) where
3074-
throwError e = lift (throwError e)
3075-
{-# INLINE throwError #-}
3076-
3077-
catchError l k = Select (catchError (enumerate l) (\e -> enumerate (k e)))
3078-
{-# INLINE catchError #-}
3079-
3080-
{- These instances require a dependency on `exceptions`.
3081-
instance MonadThrow m => MonadThrow (ListT m) where
3082-
throwM = Select . throwM
3083-
{-# INLINE throwM #-}
3084-
instance MonadCatch m => MonadCatch (ListT m) where
3085-
catch l k = Select (Control.Monad.Catch.catch (enumerate l) (\e -> enumerate (k e)))
3086-
{-# INLINE catch #-}
3087-
-}
3088-
3089-
instance Monad m => MonadZip (ListT m) where
3090-
mzipWith f = go
3091-
where
3092-
go xs ys = Select $ do
3093-
xres <- lift $ next (enumerate xs)
3094-
case xres of
3095-
Left () -> pure ()
3096-
Right (x, xrest) -> do
3097-
yres <- lift $ next (enumerate ys)
3098-
case yres of
3099-
Left () -> pure ()
3100-
Right (y, yrest) -> do
3101-
yield (f x y)
3102-
enumerate (go (Select xrest) (Select yrest))
3103-
3104-
-- | Run a self-contained 'ListT' computation
3105-
runListT :: Monad m => ListT m a -> m ()
3106-
runListT l = effects (enumerate (l >> mzero))
3107-
{-# INLINABLE runListT #-}
2926+
{-#INLINABLE mapMaybeM #-}

streaming.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ library
202202
Streaming
203203
, Streaming.Prelude
204204
, Streaming.Internal
205+
, Streaming.ListT
205206
, Data.Functor.Of
206207
other-extensions:
207208
RankNTypes

0 commit comments

Comments
 (0)