@@ -46,22 +46,15 @@ import Prelude hiding (concat)
47data Unfold m a b =
47data Unfold m a b =
48 -- | @Unfold step inject extract@
48 -- | @Unfold step inject extract@
49− forall s. Unfold (s -> m (Step s b)) (a -> m s) (s -> m (Maybe a))
49+ forall s. Unfold (s -> m (Step s b)) (a -> m s) (s -> m a)
51------------------------------------------------------------------------------
51------------------------------------------------------------------------------
53------------------------------------------------------------------------------
53------------------------------------------------------------------------------
55−-- XXX we do not need a Maybe, we can just use undefined or error. There is no
56−-- state to extract in this case, and it should not be used.
58−-- However, in certain cases we may not be able to extract, e.g. if we are
59−-- unfolding a Map, we may not be able to resume reading a Map. In such cases
60−-- it may be useful to return a Nothing. Or maybe we do not allow unfolding
62{-# INLINE nilM #-}
55{-# INLINE nilM #-}
63nilM :: Monad m => (a -> m c) -> Unfold m a b
56nilM :: Monad m => (a -> m c) -> Unfold m a b
64−nilM f = Unfold step return (\_ -> return Nothing)
57+nilM f = Unfold step return return
@@ -74,26 +67,26 @@ nil = nilM (\_ -> return ())
75{-# INLINE unfoldrM #-}
68{-# INLINE unfoldrM #-}
76unfoldrM :: Monad m => (a -> m (Maybe (b, a))) -> Unfold m a b
69unfoldrM :: Monad m => (a -> m (Maybe (b, a))) -> Unfold m a b
77−unfoldrM next = Unfold step return (return . Just)
70+unfoldrM next = Unfold step return return
79 {-# INLINE_LATE step #-}
72 {-# INLINE_LATE step #-}
80 step st = do
73 step st = do
81 r <- next st
74 r <- next st
82 return $ case r of
75 return $ case r of
83 Just (x, s) -> Yield x s
76 Just (x, s) -> Yield x s
84− Nothing -> Stop
77+ Nothing -> Stop
86-- | Convert a list of pure values to a 'Stream'
79-- | Convert a list of pure values to a 'Stream'
88-- /Internal/
81-- /Internal/
89{-# INLINE_LATE fromList #-}
82{-# INLINE_LATE fromList #-}
90fromList :: Monad m => Unfold m [a] a
83fromList :: Monad m => Unfold m [a] a
91−fromList = Unfold step inject (return . Just)
84+fromList = Unfold step inject return
93 inject = return
86 inject = return
94 {-# INLINE_LATE step #-}
87 {-# INLINE_LATE step #-}
95 step (x:xs) = return $ Yield x xs
88 step (x:xs) = return $ Yield x xs
96− step [] = return Stop
89+ step [] = return Stop
98------------------------------------------------------------------------------
91------------------------------------------------------------------------------
@@ -106,7 +99,7 @@ fromList = Unfold step inject (return . Just)
106{-# INLINE_NORMAL lmap #-}
99{-# INLINE_NORMAL lmap #-}
107lmap :: Functor m => (a -> c) -> (c -> a) -> Unfold m c b -> Unfold m a b
100lmap :: Functor m => (a -> c) -> (c -> a) -> Unfold m c b -> Unfold m a b
108lmap f g (Unfold ustep uinject uextract) =
101lmap f g (Unfold ustep uinject uextract) =
109− Unfold ustep (uinject . f) (fmap (fmap g) . uextract)
102+ Unfold ustep (uinject . f) (fmap g . uextract)
111------------------------------------------------------------------------------
104------------------------------------------------------------------------------
112-- Nesting
105-- Nesting
@@ -115,6 +108,8 @@ lmap f g (Unfold ustep uinject uextract) =
115{-# ANN type ConcatState Fuse #-}
108{-# ANN type ConcatState Fuse #-}
116data ConcatState s1 s2 = ConcatOuter s1 | ConcatInner s1 s2
109data ConcatState s1 s2 = ConcatOuter s1 | ConcatInner s1 s2
111+-- XXX Use Either a (a,b) for extracted state.
118-- | Apply the second unfold to each output element of the first unfold and
113-- | Apply the second unfold to each output element of the first unfold and
119-- flatten the output in a single stream.
114-- flatten the output in a single stream.
@@ -152,17 +147,8 @@ concat (Unfold step1 inject1 extract1) (Unfold step2 inject2 extract2) =
152 Skip s -> Skip (ConcatInner ost s)
147 Skip s -> Skip (ConcatInner ost s)
153 Stop -> Skip (ConcatOuter ost)
148 Stop -> Skip (ConcatOuter ost)
155− extract (ConcatOuter s1) = do
150+ extract (ConcatOuter s1) = (,Nothing) <$> extract1 s1
159− Just a -> Just (a, Nothing)
160 extract (ConcatInner s1 s2) = do
151 extract (ConcatInner s1 s2) = do
161 r1 <- extract1 s1
152 r1 <- extract1 s1
163− Nothing -> return Nothing
165− r2 <- extract2 s2
153+ r2 <- extract2 s2
166− return $ case r2 of
154+ return (r1, Just r2)
167− Nothing -> Just (a, Nothing)
168− Just b -> Just (a, Just b)