@@ -39,10 +39,13 @@ module Streamly.Prelude
3939 , all
4040 , any
4141 , head
42+ , tail
4243 , last
44+ , null
4345 , length
4446 , elem
4547 , notElem
48+ , reverse
4649 , maximum
4750 , minimum
4851 , sum
@@ -82,7 +85,7 @@ import Prelude hiding (filter, drop, dropWhile, take,
8285 mapM, mapM_, sequence, all, any,
8386 sum, product, elem, notElem,
8487 maximum, minimum, head, last,
85− length)
88+ tail, length, null, reverse)
8689import qualified Prelude
8790import qualified System.IO as IO
8891
@@ -333,11 +336,26 @@ head m =
333336 yield a _ = return (Just a)
334337 in (runStream (toStream m)) Nothing stop yield
335338
339+-- | Extract all but the first element of the stream, if any.
340+tail :: (Streaming t, Monad m) => t m a -> m (Maybe (t m a))
341+tail m =
342+ let stop = return Nothing
343+ yield _ Nothing = return $ Just nil
344+ yield _ (Just t) = return $ Just $ fromStream t
345+ in (runStream (toStream m)) Nothing stop yield
346+
336347-- | Extract the last element of the stream, if any.
337348{-# INLINE last #-}
338349last :: (Streaming t, Monad m) => t m a -> m (Maybe a)
339350last = foldl (\_ y -> Just y) Nothing id
340351
352+-- | Determine whether the stream is empty.
353+null :: (Streaming t, Monad m) => t m a -> m Bool
354+null m =
355+ let stop = return True
356+ yield _ _ = return False
357+ in (runStream (toStream m)) Nothing stop yield
358+
341359-- | Determine whether an element is present in the stream.
342360elem :: (Streaming t, Monad m, Eq a) => a -> t m a -> m Bool
343361elem e m = go (toStream m)
@@ -362,6 +380,19 @@ notElem e m = go (toStream m)
362380length :: (Streaming t, Monad m) => t m a -> m Int
363381length = foldl (\n _ -> n + 1) 0 id
364382
383+-- | Returns the elements of the stream in reverse order.
384+-- The stream must be finite.
385+reverse :: (Streaming t) => t m a -> t m a
386+reverse m = fromStream $ go Nothing (toStream m)
387+ where
388+ go rev rest = Stream $ \svr stp yld ->
389+ let stop = case rev of
390+ Nothing -> stp
391+ Just str -> runStream str svr stp yld
392+ yield a Nothing = runStream (a `scons` rev) svr stp yld
393+ yield a (Just x) = runStream (go (Just $ a `scons` rev) x) svr stp yld
394+ in runStream rest svr stop yield
395+
365396-- XXX replace the recursive "go" with continuation
366397-- | Determine the minimum element in a stream.
367398minimum :: (Streaming t, Monad m, Ord a) => t m a -> m (Maybe a)