enumerator-0.4.5: src/list.anansi
\section{Lists}
:f Data/Enumerator/List.hs
|Data.Enumerator.List module header|
module Data.Enumerator.List (
|Data.Enumerator.List exports|
) where
import Data.Enumerator hiding (consume, head, peek, drop, dropWhile)
import Control.Exception (ErrorCall(..))
import Prelude hiding (head, drop, dropWhile, take, takeWhile)
import qualified Data.List as L
:
:f Data/Enumerator/List.hs
|apidoc Data.Enumerator.List.head|
head :: Monad m => Iteratee a m (Maybe a)
head = continue loop where
loop (Chunks []) = head
loop (Chunks (x:xs)) = yield (Just x) (Chunks xs)
loop EOF = yield Nothing EOF
:
:f Data/Enumerator/List.hs
|apidoc Data.Enumerator.List.drop|
drop :: Monad m => Integer -> Iteratee a m ()
drop n | n <= 0 = return ()
drop n = continue (loop n) where
loop n' (Chunks xs) = iter where
len = L.genericLength xs
iter = if len < n'
then drop (n' - len)
else yield () (Chunks (L.genericDrop n' xs))
loop _ EOF = yield () EOF
:
:f Data/Enumerator/List.hs
|apidoc Data.Enumerator.List.dropWhile|
dropWhile :: Monad m => (a -> Bool) -> Iteratee a m ()
dropWhile p = continue loop where
loop (Chunks xs) = case L.dropWhile p xs of
[] -> continue loop
xs' -> yield () (Chunks xs')
loop EOF = yield () EOF
:
:f Data/Enumerator/List.hs
|apidoc Data.Enumerator.List.take|
take :: Monad m => Integer -> Iteratee a m [a]
take n | n <= 0 = return []
take n = continue (loop id n) where
len = L.genericLength
loop acc n' (Chunks xs)
| len xs < n' = continue (loop (acc . (xs ++)) (n' - len xs))
| otherwise = let
(xs', extra) = L.genericSplitAt n' xs
in yield (acc xs') (Chunks extra)
loop acc _ EOF = yield (acc []) EOF
:
:f Data/Enumerator/List.hs
|apidoc Data.Enumerator.List.takeWhile|
takeWhile :: Monad m => (a -> Bool) -> Iteratee a m [a]
takeWhile p = continue (loop id) where
loop acc (Chunks []) = continue (loop acc)
loop acc (Chunks xs) = case Prelude.span p xs of
(_, []) -> continue (loop (acc . (xs ++)))
(xs', extra) -> yield (acc xs') (Chunks extra)
loop acc EOF = yield (acc []) EOF
:
:# NOTE: peeking properly is currently impossible with the current design of
:# 'Stream'. Once it's updated to support EOF with "final data", peek can be
:# re-enabled
:#
:# :d Data/Enumerator/List.hs
:# |apidoc Data.Enumerator.List.peek|
:# peek :: Monad m => Integer -> Iteratee a m [a]
:# peek n | n <= 0 = return []
:# peek n = continue (loop id n) where
:# len = L.genericLength
:# loop acc n' (Chunks xs)
:# | len xs < n' = continue (loop (acc . (xs ++)) (n' - len xs))
:# | otherwise = let
:# xs' = L.genericTake n' xs
:# in yield (acc xs') (Chunks (acc xs))
:# loop acc _ EOF = yield (acc []) EOF
:# :
:#
:# :d Data/Enumerator/List.hs (disabled)
:# |apidoc Data.Enumerator.List.peekWhile|
:# peekWhile :: Monad m => (a -> Bool) -> Iteratee a m [a]
:# peekWhile p = continue (loop id) where
:# loop acc (Chunks []) = continue (loop acc)
:# loop acc (Chunks xs) = case Prelude.span p xs of
:# (_, []) -> continue (loop (acc . (xs ++)))
:# (xs', _) -> yield (acc xs') (Chunks (acc xs))
:# loop acc EOF = yield (acc []) EOF
:# :
:f Data/Enumerator/List.hs
|apidoc Data.Enumerator.List.consume|
consume :: Monad m => Iteratee a m [a]
consume = continue (loop id) where
loop acc (Chunks []) = continue (loop acc)
loop acc (Chunks xs) = continue (loop (acc . (xs ++)))
loop acc EOF = yield (acc []) EOF
:
:f Data/Enumerator/List.hs
|apidoc Data.Enumerator.List.require|
require :: Monad m => Integer -> Iteratee a m ()
require n | n <= 0 = return ()
require n = continue (loop id n) where
len = L.genericLength
loop acc n' (Chunks xs)
| len xs < n' = continue (loop (acc . (xs ++)) (n' - len xs))
| otherwise = yield () (Chunks (acc xs))
loop _ _ EOF = throwError (ErrorCall "require: Unexpected EOF")
:
Note: {\tt isolate} has some odd behavior regarding extra input in the
inner iteratee. Depending on how large the chunks are, extra input might
be returned in the {\tt Step}, or dropped.
This doesn't matter if {\tt joinI} is used, but might if a user is poking
around inside the {\tt Step}. Eventually, enumeratees will be modified to
avoid exposing its internal iteratee state.
:f Data/Enumerator/List.hs
|apidoc Data.Enumerator.List.isolate|
isolate :: Monad m => Integer -> Enumeratee a a m b
isolate n step | n <= 0 = return step
isolate n (Continue k) = continue loop where
len = L.genericLength
loop (Chunks []) = continue loop
loop (Chunks xs)
| len xs <= n = k (Chunks xs) >>== isolate (n - len xs)
| otherwise = let
(s1, s2) = L.genericSplitAt n xs
in k (Chunks s1) >>== (\step -> yield step (Chunks s2))
loop EOF = k EOF >>== (\step -> yield step EOF)
isolate n step = drop n >> return step
:
:d Data.Enumerator.List exports
head
, drop
, dropWhile
, take
, takeWhile
, consume
, require
, isolate
: