@@ -29,10 +29,23 @@ module Asyncly.Prelude
2929 , foldl
3030 , foldlM
3131 , uncons
32− , toHandle
3332
34− -- * Special folds
33+ -- * Elimination Special Folds
3534 , toList
35+ , toHandle
36+ , all
37+ , any
38+ , sum
39+ , product
40+ , head
41+ , last
42+ , length
43+ , elem
44+ , notElem
45+ , maximum
46+ , minimum
47+
48+ -- * Filtering
3649 , filter
3750 , take
3851 , takeWhile
@@ -57,7 +70,10 @@ import Control.Monad.IO.Class (MonadIO(..))
5770import Data.Semigroup (Semigroup(..))
5871import Prelude hiding (filter, drop, dropWhile, take,
5972 takeWhile, zipWith, foldr, foldl,
60− mapM, mapM_, sequence)
73+ mapM, mapM_, sequence, all, any,
74+ sum, product, elem, notElem,
75+ maximum, minimum, head, last,
76+ length)
6177import qualified System.IO as IO
6278
6379import Asyncly.Core
@@ -223,6 +239,105 @@ dropWhile p m = fromStream $ go (toStream m)
223239 | otherwise = yld a (Just x)
224240 in (runStream m1) ctx stp yield
225241
242+-- | Determine whether all elements of a stream satisfy a predicate.
243+all :: (Streaming t, Monad m) => (a -> Bool) -> t m a -> m Bool
244+all p m = go (toStream m)
245+ where
246+ go m1 =
247+ let yield a Nothing | p a = return True
248+ | otherwise = return False
249+ yield a (Just x) | p a = go x
250+ | otherwise = return False
251+ in (runStream m1) Nothing (return True) yield
252+
253+-- | Determine whether any of the elements of a stream satisfy a predicate.
254+any :: (Streaming t, Monad m) => (a -> Bool) -> t m a -> m Bool
255+any p m = go (toStream m)
256+ where
257+ go m1 =
258+ let yield a Nothing | p a = return True
259+ | otherwise = return False
260+ yield a (Just x) | p a = return True
261+ | otherwise = go x
262+ in (runStream m1) Nothing (return False) yield
263+
264+-- | Determine the sum of all elements of a stream of numbers
265+sum :: (Streaming t, Monad m, Num a) => t m a -> m a
266+sum = foldl (+) 0 id
267+
268+-- | Determine the product of all elements of a stream of numbers
269+product :: (Streaming t, Monad m, Num a) => t m a -> m a
270+product = foldl (*) 0 id
271+
272+-- | Extract the first element of the stream, if any.
273+head :: (Streaming t, Monad m) => t m a -> m (Maybe a)
274+head m =
275+ let stop = return Nothing
276+ yield a _ = return (Just a)
277+ in (runStream (toStream m)) Nothing stop yield
278+
279+-- | Extract the first element of the stream, if any.
280+last :: (Streaming t, Monad m) => t m a -> m (Maybe a)
281+last m = go (toStream m)
282+ where
283+ go m1 =
284+ let stop = return Nothing
285+ yield a Nothing = return (Just a)
286+ yield _ (Just x) = go x
287+ in (runStream m1) Nothing stop yield
288+
289+-- | Determine whether an element is present in the stream.
290+elem :: (Streaming t, Monad m, Eq a) => a -> t m a -> m Bool
291+elem e m = go (toStream m)
292+ where
293+ go m1 =
294+ let stop = return False
295+ yield a Nothing = return (a == e)
296+ yield a (Just x) = if (a == e) then return True else go x
297+ in (runStream m1) Nothing stop yield
298+
299+-- | Determine whether an element is not present in the stream.
300+notElem :: (Streaming t, Monad m, Eq a) => a -> t m a -> m Bool
301+notElem e m = go (toStream m)
302+ where
303+ go m1 =
304+ let stop = return True
305+ yield a Nothing = return (a /= e)
306+ yield a (Just x) = if (a == e) then return False else go x
307+ in (runStream m1) Nothing stop yield
308+
309+-- | Determine the length of the stream.
310+length :: (Streaming t, Monad m) => t m a -> m Int
311+length = foldl (\n _ -> n + 1) 0 id
312+
313+-- | Determine the minimum element in a stream.
314+minimum :: (Streaming t, Monad m, Ord a) => t m a -> m (Maybe a)
315+minimum m = go Nothing (toStream m)
316+ where
317+ go r m1 =
318+ let stop = return r
319+ yield a Nothing = return $ min_ a r
320+ yield a (Just x) = go (min_ a r) x
321+ in (runStream m1) Nothing stop yield
322+
323+ min_ a r = case r of
324+ Nothing -> Just a
325+ Just e -> Just $ min a e
326+
327+-- | Determine the maximum element in a stream.
328+maximum :: (Streaming t, Monad m, Ord a) => t m a -> m (Maybe a)
329+maximum m = go Nothing (toStream m)
330+ where
331+ go r m1 =
332+ let stop = return r
333+ yield a Nothing = return $ max_ a r
334+ yield a (Just x) = go (max_ a r) x
335+ in (runStream m1) Nothing stop yield
336+
337+ max_ a r = case r of
338+ Nothing -> Just a
339+ Just e -> Just $ max a e
340+
226341------------------------------------------------------------------------------
227342-- Transformation
228343------------------------------------------------------------------------------