Ticket #4270: small.hs

File small.hs, 5.8 KB (added by igloo, 21 months ago)
Line 
1{-# LANGUAGE CPP, ExistentialQuantification, Rank2Types #-}
2
3#ifdef USE_PRAGMAS
4#define INPRAG(f)  {-# INLINE f #-}
5#define INPRAG0(f) {-# INLINE [0] f #-}
6#define INPRAG1(f) {-# INLINE [1] f #-}
7#else
8#define INPRAG(f)
9#define INPRAG0(f)
10#define INPRAG1(f)
11#endif
12
13module Data.Vector.Fusion.Stream.Monadic where
14
15import Control.Monad  (liftM)
16import Prelude        (Monad(..), Int, Ord(..), ($), Maybe(..))
17
18data Step s a = Yield a s
19              | Skip    s
20              | Done
21
22data Stream m a = forall s. Stream (s -> m (Step s a)) s Size
23
24zipWithM :: Monad m => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
25INPRAG1(zipWithM)
26zipWithM f (Stream stepa sa0 na) (Stream stepb sb0 nb)
27  = Stream step (sa0, sb0, Nothing) (smaller na nb)
28  where
29    INPRAG0(step)
30    step (sa, sb, Nothing) = liftM (\r ->
31                               case r of
32                                 Yield x sa' -> Skip (sa', sb, Just x)
33                                 Skip    sa' -> Skip (sa', sb, Nothing)
34                                 Done        -> Done
35                             ) (stepa sa)
36
37    step (sa, sb, Just x)  = do
38                               r <- stepb sb
39                               case r of
40                                 Yield y sb' ->
41                                   do
42                                     z <- f x y
43                                     return $ Yield z (sa, sb', Nothing)
44                                 Skip    sb' -> return $ Skip (sa, sb', Just x)
45                                 Done        -> return $ Done
46
47zipWith3M :: Monad m => (a -> b -> c -> m d) -> Stream m a -> Stream m b -> Stream m c -> Stream m d
48INPRAG1(zipWith3M)
49zipWith3M f (Stream stepa sa0 na) (Stream stepb sb0 nb) (Stream stepc sc0 nc)
50  = Stream step (sa0, sb0, sc0, Nothing) (smaller na (smaller nb nc))
51  where
52    INPRAG0(step)
53    step (sa, sb, sc, Nothing) = do
54        r <- stepa sa
55        return $ case r of
56            Yield x sa' -> Skip (sa', sb, sc, Just (x, Nothing))
57            Skip    sa' -> Skip (sa', sb, sc, Nothing)
58            Done        -> Done
59
60    step (sa, sb, sc, Just (x, Nothing)) = do
61        r <- stepb sb
62        return $ case r of
63            Yield y sb' -> Skip (sa, sb', sc, Just (x, Just y))
64            Skip    sb' -> Skip (sa, sb', sc, Just (x, Nothing))
65            Done        -> Done
66
67    step (sa, sb, sc, Just (x, Just y)) = do
68        r <- stepc sc
69        case r of
70            Yield z sc' -> f x y z >>= (\res -> return $ Yield res (sa, sb, sc', Nothing))
71            Skip    sc' -> return $ Skip (sa, sb, sc', Just (x, Just y))
72            Done        -> return $ Done
73
74zipWith4M :: Monad m => (a -> b -> c -> d -> m e)
75                     -> Stream m a -> Stream m b -> Stream m c -> Stream m d
76                     -> Stream m e
77INPRAG(zipWith4M)
78zipWith4M f sa sb sc sd
79  = zipWithM (\(a,b) (c,d) -> f a b c d) (zip sa sb) (zip sc sd)
80
81zipWith5M :: Monad m => (a -> b -> c -> d -> e -> m f)
82                     -> Stream m a -> Stream m b -> Stream m c -> Stream m d
83                     -> Stream m e -> Stream m f
84INPRAG(zipWith5M)
85zipWith5M f sa sb sc sd se
86  = zipWithM (\(a,b,c) (d,e) -> f a b c d e) (zip3 sa sb sc) (zip sd se)
87
88zipWith6M :: Monad m => (a -> b -> c -> d -> e -> f -> m g)
89                     -> Stream m a -> Stream m b -> Stream m c -> Stream m d
90                     -> Stream m e -> Stream m f -> Stream m g
91INPRAG(zipWith6M)
92zipWith6M fn sa sb sc sd se sf
93  = zipWithM (\(a,b,c) (d,e,f) -> fn a b c d e f) (zip3 sa sb sc)
94                                                  (zip3 sd se sf)
95
96zipWith :: Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
97INPRAG(zipWith)
98zipWith f = zipWithM (\a b -> return (f a b))
99
100zipWith3 :: Monad m => (a -> b -> c -> d)
101                    -> Stream m a -> Stream m b -> Stream m c -> Stream m d
102INPRAG(zipWith3)
103zipWith3 f = zipWith3M (\a b c -> return (f a b c))
104
105zipWith4 :: Monad m => (a -> b -> c -> d -> e)
106                    -> Stream m a -> Stream m b -> Stream m c -> Stream m d
107                    -> Stream m e
108INPRAG(zipWith4)
109zipWith4 f = zipWith4M (\a b c d -> return (f a b c d))
110
111zipWith5 :: Monad m => (a -> b -> c -> d -> e -> f)
112                    -> Stream m a -> Stream m b -> Stream m c -> Stream m d
113                    -> Stream m e -> Stream m f
114INPRAG(zipWith5)
115zipWith5 f = zipWith5M (\a b c d e -> return (f a b c d e))
116
117zipWith6 :: Monad m => (a -> b -> c -> d -> e -> f -> g)
118                    -> Stream m a -> Stream m b -> Stream m c -> Stream m d
119                    -> Stream m e -> Stream m f -> Stream m g
120INPRAG(zipWith6)
121zipWith6 fn = zipWith6M (\a b c d e f -> return (fn a b c d e f))
122
123zip :: Monad m => Stream m a -> Stream m b -> Stream m (a,b)
124INPRAG(zip)
125zip = zipWith (,)
126
127zip3 :: Monad m => Stream m a -> Stream m b -> Stream m c -> Stream m (a,b,c)
128INPRAG(zip3)
129zip3 = zipWith3 (,,)
130
131zip4 :: Monad m => Stream m a -> Stream m b -> Stream m c -> Stream m d
132                -> Stream m (a,b,c,d)
133INPRAG(zip4)
134zip4 = zipWith4 (,,,)
135
136zip5 :: Monad m => Stream m a -> Stream m b -> Stream m c -> Stream m d
137                -> Stream m e -> Stream m (a,b,c,d,e)
138INPRAG(zip5)
139zip5 = zipWith5 (,,,,)
140
141zip6 :: Monad m => Stream m a -> Stream m b -> Stream m c -> Stream m d
142                -> Stream m e -> Stream m f -> Stream m (a,b,c,d,e,f)
143INPRAG(zip6)
144zip6 = zipWith6 (,,,,,)
145
146delay_inline :: (a -> b) -> a -> b
147delay_inline f = f
148
149data Size = Exact Int
150          | Max   Int
151          | Unknown
152
153smaller :: Size -> Size -> Size
154INPRAG(smaller)
155smaller (Exact m) (Exact n) = Exact (min m n)
156smaller (Exact m) (Max   n) = Max   (min m n)
157smaller (Exact m) Unknown   = Max   m
158smaller (Max   m) (Exact n) = Max   (min m n)
159smaller (Max   m) (Max   n) = Max   (min m n)
160smaller (Max   m) Unknown   = Max   m
161smaller Unknown   (Exact n) = Max   n
162smaller Unknown   (Max   n) = Max   n
163smaller Unknown   Unknown   = Unknown