-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Effectful, iteratee-inspired stream processing based on a
free monad.
--
@package tubes
@version 0.1.0.0
module Tubes.Core
-- | A Tube is the free monad transformer arising from TubeF.
type Tube a b m r = FreeT (TubeF a b) m r
-- | TubeF is the union of unary functions and binary products into
-- a single type, here defined with a Boehm-Berarducci encoding.
--
-- Rather than using a normal ADT, which would certainly make the code a
-- bit easier to read and write, a value of this type is actually a
-- control flow mechanism accepting two continuations and choosing one or
-- the other.
--
-- Client code should never actually have to deal with this.
newtype TubeF a b k
TubeF :: (forall r. ((a -> k) -> r) -> ((b, k) -> r) -> r) -> TubeF a b k
runT :: TubeF a b k -> forall r. ((a -> k) -> r) -> ((b, k) -> r) -> r
-- | A computation which only yields and never awaits
type Source b m r = forall x. Tube x b m r
-- | A computation which only awaits and never yields
type Sink a m r = forall x. Tube a x m r
-- | A computation which neither yields nor awaits
type Action m r = forall x. Tube x x m r
-- | run is shorter than runFreeT and who knows, maybe it'll
-- change some day
run :: FreeT f m a -> m (FreeF f a (FreeT f m a))
-- | Command to wait for a new value upstream
await :: Monad m => Tube a b m a
-- | Command to send a value downstream
yield :: Monad m => b -> Tube a b m ()
-- | Constructor for source computations
yieldF :: b -> k -> TubeF a b k
-- | Constructor for sink computations
awaitF :: (a -> k) -> TubeF a b k
-- | This performs a neat trick: a Tube with a return type
-- a will be turned into a new Tube containing the
-- underlying TubeF value.
--
-- In this way the >< and >- functions can replace
-- the () return value with a continuation and recursively
-- traverse the computation until a final result is reached.
liftT :: (MonadTrans t, Monad m) => FreeT f m a -> t m (FreeF f a (FreeT f m a))
-- | Convert a list to a Source
each :: (Monad m, Foldable t) => t b -> Tube a b m ()
-- | Enumerate yielded values into a continuation, creating a new
-- Source
for :: Monad m => Tube a b m r -> (b -> Tube a c m s) -> Tube a c m r
-- | Compose two tasks in a pull-based stream
(><) :: Monad m => Tube a b m r -> Tube b c m r -> Tube a c m r
-- | Connect a task to a continuation yielding another task; see
-- ><
(>-) :: Monad m => Tube a b m r -> (b -> Tube b c m r) -> Tube a c m r
-- | Infix version of for
(~>) :: Monad m => Tube a b m r -> (b -> Tube a c m s) -> Tube a c m r
instance Functor (TubeF a b)
module Tubes.Util
-- | Continuously relays any values it receives. Iteratee identity.
cat :: Monad m => Tube a a m r
-- | Transforms all incoming values according to some function.
map :: Monad m => (a -> b) -> Tube a b m r
-- | Refuses to yield the first n values it receives.
drop :: Monad m => Int -> Tube a a m r
-- | Relay only the first n elements of a stream.
take :: Monad m => Int -> Tube a a m ()
-- | Terminates the stream upon receiving a value violating the predicate
takeWhile :: Monad m => (a -> Bool) -> Tube a a m ()
-- | Yields only values satisfying some predicate.
filter :: Monad m => (a -> Bool) -> Tube a a m r
-- | Strict left-fold of a stream
reduce :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Source a m () -> m b
-- | Similar to each except it explicitly marks the stream as
-- exhausted
every :: (Foldable t, Monad m) => t b -> Tube a (Maybe b) m ()
-- | Source of Strings from stdin. This is mostly for debugging /
-- ghci example purposes.
prompt :: Source String IO ()
-- | Sink for Strings to stdout. This is mostly for debugging / ghci
-- example purposes.
display :: Sink String IO ()
-- | Taps the next value from a source.
unyield :: Monad m => Source b m () -> m (Maybe b)
-- | This exists primarily for my own education. It is updated often as I
-- try things and is probably, at this moment, wrong.
--
-- If you want to know more about iteratees:
--
-- http://okmij.org/ftp/Streams.html
--
-- My goals were to (1) learn more about iteratees and (2) see how far I
-- could get using free monads.
module Tubes
-- | TubeF is the union of unary functions and binary products into
-- a single type, here defined with a Boehm-Berarducci encoding.
--
-- Rather than using a normal ADT, which would certainly make the code a
-- bit easier to read and write, a value of this type is actually a
-- control flow mechanism accepting two continuations and choosing one or
-- the other.
--
-- Client code should never actually have to deal with this.
newtype TubeF a b k
TubeF :: (forall r. ((a -> k) -> r) -> ((b, k) -> r) -> r) -> TubeF a b k
runT :: TubeF a b k -> forall r. ((a -> k) -> r) -> ((b, k) -> r) -> r
-- | A Tube is the free monad transformer arising from TubeF.
type Tube a b m r = FreeT (TubeF a b) m r
-- | A computation which only yields and never awaits
type Source b m r = forall x. Tube x b m r
-- | A computation which only awaits and never yields
type Sink a m r = forall x. Tube a x m r
-- | A computation which neither yields nor awaits
type Action m r = forall x. Tube x x m r
-- | Lift a computation from the argument monad to the constructed monad.
lift :: MonadTrans t => forall (m :: * -> *) a. Monad m => m a -> t m a
runFreeT :: FreeT f m a -> m (FreeF f a (FreeT f m a))
-- | Command to wait for a new value upstream
await :: Monad m => Tube a b m a
-- | Command to send a value downstream
yield :: Monad m => b -> Tube a b m ()
-- | Constructor for sink computations
awaitF :: (a -> k) -> TubeF a b k
-- | Constructor for source computations
yieldF :: b -> k -> TubeF a b k
-- | Convert a list to a Source
each :: (Monad m, Foldable t) => t b -> Tube a b m ()
-- | Enumerate yielded values into a continuation, creating a new
-- Source
for :: Monad m => Tube a b m r -> (b -> Tube a c m s) -> Tube a c m r
-- | Infix version of for
(~>) :: Monad m => Tube a b m r -> (b -> Tube a c m s) -> Tube a c m r
-- | Connect a task to a continuation yielding another task; see
-- ><
(>-) :: Monad m => Tube a b m r -> (b -> Tube b c m r) -> Tube a c m r
-- | Compose two tasks in a pull-based stream
(><) :: Monad m => Tube a b m r -> Tube b c m r -> Tube a c m r
-- | run is shorter than runFreeT and who knows, maybe it'll
-- change some day
run :: FreeT f m a -> m (FreeF f a (FreeT f m a))
-- | This performs a neat trick: a Tube with a return type
-- a will be turned into a new Tube containing the
-- underlying TubeF value.
--
-- In this way the >< and >- functions can replace
-- the () return value with a continuation and recursively
-- traverse the computation until a final result is reached.
liftT :: (MonadTrans t, Monad m) => FreeT f m a -> t m (FreeF f a (FreeT f m a))
-- | Continuously relays any values it receives. Iteratee identity.
cat :: Monad m => Tube a a m r
-- | Transforms all incoming values according to some function.
map :: Monad m => (a -> b) -> Tube a b m r
-- | Refuses to yield the first n values it receives.
drop :: Monad m => Int -> Tube a a m r
-- | Relay only the first n elements of a stream.
take :: Monad m => Int -> Tube a a m ()
-- | Terminates the stream upon receiving a value violating the predicate
takeWhile :: Monad m => (a -> Bool) -> Tube a a m ()
-- | Yields only values satisfying some predicate.
filter :: Monad m => (a -> Bool) -> Tube a a m r
-- | Strict left-fold of a stream
reduce :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Source a m () -> m b
-- | Similar to each except it explicitly marks the stream as
-- exhausted
every :: (Foldable t, Monad m) => t b -> Tube a (Maybe b) m ()
-- | Taps the next value from a source.
unyield :: Monad m => Source b m () -> m (Maybe b)
-- | Source of Strings from stdin. This is mostly for debugging /
-- ghci example purposes.
prompt :: Source String IO ()
-- | Sink for Strings to stdout. This is mostly for debugging / ghci
-- example purposes.
display :: Sink String IO ()