on master help sign in
Merge branch 'Veladus-master'
7c997d8Harendra Kumar
src/Streamly/Prelude.hs+32−1
@@ -39,10 +39,13 @@ module Streamly.Prelude
39 , all
39 , all
40 , any
40 , any
41 , head
41 , head
42+ , tail
42 , last
43 , last
44+ , null
43 , length
45 , length
44 , elem
46 , elem
45 , notElem
47 , notElem
48+ , reverse
46 , maximum
49 , maximum
47 , minimum
50 , minimum
48 , sum
51 , sum
@@ -82,7 +85,7 @@ import Prelude hiding (filter, drop, dropWhile, take,
82 mapM, mapM_, sequence, all, any,
85 mapM, mapM_, sequence, all, any,
83 sum, product, elem, notElem,
86 sum, product, elem, notElem,
84 maximum, minimum, head, last,
87 maximum, minimum, head, last,
85− length)
88+ tail, length, null, reverse)
86import qualified Prelude
89import qualified Prelude
87import qualified System.IO as IO
90import qualified System.IO as IO
88
91
@@ -333,11 +336,26 @@ head m =
333 yield a _ = return (Just a)
336 yield a _ = return (Just a)
334 in (runStream (toStream m)) Nothing stop yield
337 in (runStream (toStream m)) Nothing stop yield
335
338
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+
336-- | Extract the last element of the stream, if any.
347-- | Extract the last element of the stream, if any.
337{-# INLINE last #-}
348{-# INLINE last #-}
338last :: (Streaming t, Monad m) => t m a -> m (Maybe a)
349last :: (Streaming t, Monad m) => t m a -> m (Maybe a)
339last = foldl (\_ y -> Just y) Nothing id
350last = foldl (\_ y -> Just y) Nothing id
340
351
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+
341-- | Determine whether an element is present in the stream.
359-- | Determine whether an element is present in the stream.
342elem :: (Streaming t, Monad m, Eq a) => a -> t m a -> m Bool
360elem :: (Streaming t, Monad m, Eq a) => a -> t m a -> m Bool
343elem e m = go (toStream m)
361elem e m = go (toStream m)
@@ -362,6 +380,19 @@ notElem e m = go (toStream m)
362length :: (Streaming t, Monad m) => t m a -> m Int
380length :: (Streaming t, Monad m) => t m a -> m Int
363length = foldl (\n _ -> n + 1) 0 id
381length = foldl (\n _ -> n + 1) 0 id
364
382
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+
365-- XXX replace the recursive "go" with continuation
396-- XXX replace the recursive "go" with continuation
366-- | Determine the minimum element in a stream.
397-- | Determine the minimum element in a stream.
367minimum :: (Streaming t, Monad m, Ord a) => t m a -> m (Maybe a)
398minimum :: (Streaming t, Monad m, Ord a) => t m a -> m (Maybe a)
test/Main.hs+13−3
@@ -7,6 +7,7 @@ import Control.Concurrent (threadDelay)
7import Control.Monad (replicateM)
7import Control.Monad (replicateM)
8import Data.Foldable (forM_)
8import Data.Foldable (forM_)
9import Data.List (sort)
9import Data.List (sort)
10+import Data.Maybe (fromJust)
10import Test.Hspec
11import Test.Hspec
11
12
12import Streamly
13import Streamly
@@ -675,7 +676,9 @@ streamOperations (stream, list, len) = do
675 it "dropWhile < some" $ transform (A.dropWhile (< (len `div` 2)))
676 it "dropWhile < some" $ transform (A.dropWhile (< (len `div` 2)))
676 (dropWhile (< (len `div` 2)))
677 (dropWhile (< (len `div` 2)))
677
678
679+ -- Transformations
678 it "scan left" $ transform (A.scan (+) 0 id) (scanl (+) 0)
680 it "scan left" $ transform (A.scan (+) 0 id) (scanl (+) 0)
681+ it "reverse" $ transform A.reverse reverse
679
682
680 -- Elimination
683 -- Elimination
681 it "foldl" $ elimination (A.foldl (+) 0 id) (foldl (+) 0)
684 it "foldl" $ elimination (A.foldl (+) 0 id) (foldl (+) 0)
@@ -695,14 +698,21 @@ streamOperations (stream, list, len) = do
695 it "last empty" $ A.last stream `shouldReturn` Nothing
698 it "last empty" $ A.last stream `shouldReturn` Nothing
696 it "maximum empty" $ A.maximum stream `shouldReturn` Nothing
699 it "maximum empty" $ A.maximum stream `shouldReturn` Nothing
697 it "minimum empty" $ A.minimum stream `shouldReturn` Nothing
700 it "minimum empty" $ A.minimum stream `shouldReturn` Nothing
701+ it "null empty" $ A.null stream `shouldReturn` True
702+ it "tail empty" $ (A.tail stream >>= return . maybe True (const False))
703+ `shouldReturn` True
698 else do
704 else do
699 it "head nonEmpty" $ A.head stream `shouldReturn` Just (head list)
705 it "head nonEmpty" $ A.head stream `shouldReturn` Just (head list)
700 it "last nonEmpty" $ A.last stream `shouldReturn` Just (last list)
706 it "last nonEmpty" $ A.last stream `shouldReturn` Just (last list)
701− it "maximum nonEmpty" $ A.maximum stream `shouldReturn` Just (maximum list)
707+ it "maximum nonEmpty" $ A.maximum stream
708+ `shouldReturn` Just (maximum list)
702− it "minimum nonEmpty" $ A.minimum stream `shouldReturn` Just (minimum list)
709+ it "minimum nonEmpty" $ A.minimum stream
710+ `shouldReturn` Just (minimum list)
711+ it "null nonEmpty" $ A.null stream `shouldReturn` False
712+ it "tail nonEmpty" $ (A.tail stream >>= A.toList . fromJust)
713+ `shouldReturn` tail list
703
714
704 where
715 where
705−
706 -- XXX run on empty stream as well
716 -- XXX run on empty stream as well
707 transform streamOp listOp =
717 transform streamOp listOp =
708 (A.toList $ streamOp stream) `shouldReturn` listOp list
718 (A.toList $ streamOp stream) `shouldReturn` listOp list