Safe Haskell | None |
---|---|
Language | Haskell2010 |
- data Stream f m r
- unfold :: (Monad m, Functor f) => (s -> m (Either r (f s))) -> s -> Stream f m r
- for :: (Monad m, Functor f) => Stream (Of a) m r -> (a -> Stream f m x) -> Stream f m r
- construct :: (forall b. (f b -> b) -> (m b -> b) -> (r -> b) -> b) -> Stream f m r
- replicates :: (Monad m, Functor f) => Int -> f () -> Stream f m ()
- repeats :: (Monad m, Functor f) => f () -> Stream f m r
- repeatsM :: (Monad m, Functor f) => m (f ()) -> Stream f m r
- maps :: (Monad m, Functor f) => (forall x. f x -> g x) -> Stream f m r -> Stream g m r
- maps' :: (Monad m, Functor f) => (forall x. f x -> m (a, x)) -> Stream f m r -> Stream (Of a) m r
- mapsM :: (Monad m, Functor f) => (forall x. f x -> m (g x)) -> Stream f m r -> Stream g m r
- distribute :: (Monad m, Functor f, MonadTrans t, MFunctor t, Monad (t (Stream f m))) => Stream f (t m) r -> t (Stream f m) r
- inspect :: (Functor f, Monad m) => Stream f m r -> m (Either r (f (Stream f m r)))
- destroy :: (Functor f, Monad m) => Stream f m r -> (f b -> b) -> (m b -> b) -> (r -> b) -> b
- intercalates :: (Monad m, Monad (t m), MonadTrans t) => t m a -> Stream (t m) m b -> t m b
- concats :: (MonadTrans t, Monad (t m), Monad m) => Stream (t m) m a -> t m a
- iterTM :: (Functor f, Monad m, MonadTrans t, Monad (t m)) => (f (t m a) -> t m a) -> Stream f m a -> t m a
- iterT :: (Functor f, Monad m) => (f (m a) -> m a) -> Stream f m a -> m a
- splitsAt :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m (Stream f m r)
- chunksOf :: (Monad m, Functor f) => Int -> Stream f m r -> Stream (Stream f m) m r
- concats :: (MonadTrans t, Monad (t m), Monad m) => Stream (t m) m a -> t m a
- data Of a b = !a :> b
- lazily :: Of a b -> (a, b)
- strictly :: (a, b) -> Of a b
- class MFunctor t where
- class MonadTrans t where
Free monad transformer
The Stream
data type is equivalent to FreeT
and can represent any effectful
succession of steps, where the form of the steps or commands
is
specified by the first (functor) parameter.
data Stream f m r = Step !(f (Stream f m r)) | Delay (m (Stream f m r)) | Return r
In the simplest case, the base functor is (,) a
. Here the news
or command at each step is an individual element of type a
,
i.e. a yield
statement. In Prelude
, (a,b)
is
replaced by the left-strict pair Of a b
. Various operations are
defined for types like
Stream (Of a) m r -- a producer in the pipes sense -- i.e. an effectful, streaming [a], or rather ([a],r) Stream (Of a) m (Stream (Of a) m r) -- the effectful splitting of a producer -- i.e. an effectful ([a],[a]) or rather ([a],([a],r)) Stream (Stream (Of a) m) m r -- successive, segmentation of a producer -- i.e. [[a]], or ([a],([a],([a]... r)))
and so on. But of course any functor can be used. So, for example,
Stream ((->) input) m result
is a simple Consumer input m result
or Parser input m result
type. And so on.
See e.g. http://www.haskellforall.com/2012/07/purify-code-using-free-monads.html ,
http://www.haskellforall.com/2012/07/free-monad-transformers.html and similar
literature.
To avoid breaking reasoning principles, the constructors
should not be used directly. A pattern-match should go by way of inspect
- or, in the producer case, next
The constructors are exported by the Internal
module.
Functor f => MFunctor (Stream f) Source | |
Functor f => MMonad (Stream f) Source | |
Functor f => MonadTrans (Stream f) Source | |
(Functor f, Monad m) => Monad (Stream f m) Source | |
(Functor f, Monad m) => Functor (Stream f m) Source | |
(Functor f, Monad m) => Applicative (Stream f m) Source | |
(MonadIO m, Functor f) => MonadIO (Stream f m) Source | |
(Eq r, Eq (m (Stream f m r)), Eq (f (Stream f m r))) => Eq (Stream f m r) Source | |
(Typeable (* -> *) f, Typeable (* -> *) m, Data r, Data (m (Stream f m r)), Data (f (Stream f m r))) => Data (Stream f m r) Source | |
(Show r, Show (m (Stream f m r)), Show (f (Stream f m r))) => Show (Stream f m r) Source |
Constructing a Stream
on a base functor
unfold :: (Monad m, Functor f) => (s -> m (Either r (f s))) -> s -> Stream f m r Source
Build a Stream
by unfolding steps starting from a seed. See also
the specialized unfoldr
in the prelude.
unfold inspect = id -- modulo the quotient we work with unfold Pipes.next :: Monad m => Producer a m r -> Stream ((,) a) m r unfold (curry (:>) . Pipes.next) :: Monad m => Producer a m r -> Stream (Of a) m r
for :: (Monad m, Functor f) => Stream (Of a) m r -> (a -> Stream f m x) -> Stream f m r Source
for
replaces each element of a stream with an associated stream. Note that the
associated stream may layer any functor.
construct :: (forall b. (f b -> b) -> (m b -> b) -> (r -> b) -> b) -> Stream f m r Source
Reflect a church-encoded stream; cp. GHC.Exts.build
replicates :: (Monad m, Functor f) => Int -> f () -> Stream f m () Source
Repeat a functorial layer, command or instruct several times.
repeats :: (Monad m, Functor f) => f () -> Stream f m r Source
Repeat a functorial layer, command or instruction forever.
Transforming streams
maps :: (Monad m, Functor f) => (forall x. f x -> g x) -> Stream f m r -> Stream g m r Source
Map layers of one functor to another with a natural transformation
maps' :: (Monad m, Functor f) => (forall x. f x -> m (a, x)) -> Stream f m r -> Stream (Of a) m r Source
Map free layers of a functor to a corresponding stream of individual elements. This
simplifies the use of folds marked with a ''' in Streaming.Prelude
maps' sum' :: (Monad m, Num a) => Stream (Stream (Of a) m) m r -> Stream (Of a) m r maps' (Pipes.fold' (+) (0::Int) id) :: Monad m => Stream (Producer Int m) m r -> Stream (Of Int) m r
mapsM :: (Monad m, Functor f) => (forall x. f x -> m (g x)) -> Stream f m r -> Stream g m r Source
Map layers of one functor to another with a transformation involving the base monad
distribute :: (Monad m, Functor f, MonadTrans t, MFunctor t, Monad (t (Stream f m))) => Stream f (t m) r -> t (Stream f m) r Source
Make it possible to 'run' the underlying transformed monad. A simple minded example might be:
debugFibs = flip runStateT 1 $ distribute $ loop 1 where loop n = do S.yield n s <- lift get liftIO $ putStr "Current state is: " >> print s lift $ put (s + n :: Int) loop s
>>>
S.print $ S.take 4 $ S.drop 4 $ debugFibs
Current state is: 1 Current state is: 2 Current state is: 3 Current state is: 5 5 Current state is: 8 8 Current state is: 13 13 Current state is: 21 21
Inspecting a stream
inspect :: (Functor f, Monad m) => Stream f m r -> m (Either r (f (Stream f m r))) Source
Inspect the first stage of a freely layered sequence.
Compare Pipes.next
and the replica Streaming.Prelude.next
.
This is the uncons
for the general unfold
.
unfold inspect = id Streaming.Prelude.unfoldr StreamingPrelude.next = id
Eliminating a Stream
destroy :: (Functor f, Monad m) => Stream f m r -> (f b -> b) -> (m b -> b) -> (r -> b) -> b Source
Map a stream to its church encoding; compare Data.List.foldr
intercalates :: (Monad m, Monad (t m), MonadTrans t) => t m a -> Stream (t m) m b -> t m b Source
Interpolate a layer at each segment. This specializes to e.g.
intercalates :: (Monad m, Functor f) => Stream f m () -> Stream (Stream f m) m r -> Stream f m r
concats :: (MonadTrans t, Monad (t m), Monad m) => Stream (t m) m a -> t m a Source
This specializes to the more transparent case:
concats :: (Monad m, Functor f) => Stream (Stream f m) m r -> Stream f m r
Thus dissolving the segmentation into Stream f m
layers.
concats stream = destroy stream join (join . lift) return
>>>
S.print $ concats $ maps (cons 1776) $ chunksOf 2 (each [1..5])
1776 1 2 1776 3 4 1776 5
iterTM :: (Functor f, Monad m, MonadTrans t, Monad (t m)) => (f (t m a) -> t m a) -> Stream f m a -> t m a Source
Specialized fold
iterTM alg stream = destroy stream alg (join . lift) return
iterT :: (Functor f, Monad m) => (f (m a) -> m a) -> Stream f m a -> m a Source
Specialized fold
iterT alg stream = destroy stream alg join return
Splitting and joining Stream
s
splitsAt :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m (Stream f m r) Source
Split a succession of layers after some number, returning a streaming or effectful pair.
>>>
rest <- S.print $ S.splitAt 1 $ each [1..3]
1>>>
S.print rest
2 3
chunksOf :: (Monad m, Functor f) => Int -> Stream f m r -> Stream (Stream f m) m r Source
Break a stream into substreams each with n functorial layers.
>>>
S.print $ maps' sum' $ chunksOf 2 $ each [1,1,1,1,1,1,1]
2 2 2 1
concats :: (MonadTrans t, Monad (t m), Monad m) => Stream (t m) m a -> t m a Source
This specializes to the more transparent case:
concats :: (Monad m, Functor f) => Stream (Stream f m) m r -> Stream f m r
Thus dissolving the segmentation into Stream f m
layers.
concats stream = destroy stream join (join . lift) return
>>>
S.print $ concats $ maps (cons 1776) $ chunksOf 2 (each [1..5])
1776 1 2 1776 3 4 1776 5
Useful functors
A left-strict pair; the base functor for streams of individual elements.
!a :> b infixr 4 |
re-exports
class MFunctor t where
A functor in the category of monads, using hoist
as the analog of fmap
:
hoist (f . g) = hoist f . hoist g hoist id = id
hoist :: Monad m => (forall a. m a -> n a) -> t m b -> t n b
Lift a monad morphism from m
to n
into a monad morphism from
(t m)
to (t n)
MFunctor ListT | |
MFunctor Backwards | |
MFunctor MaybeT | |
MFunctor IdentityT | |
MFunctor Lift | |
MFunctor (ReaderT r) | |
MFunctor (StateT s) | |
MFunctor (StateT s) | |
MFunctor (ExceptT e) | |
MFunctor (ErrorT e) | |
MFunctor (WriterT w) | |
MFunctor (WriterT w) | |
MFunctor (Product f) | |
Functor f => MFunctor (Compose f) | |
Functor f => MFunctor (Stream f) | |
MFunctor (RWST r w s) | |
MFunctor (RWST r w s) |
class MonadTrans t where
The class of monad transformers. Instances should satisfy the
following laws, which state that lift
is a monad transformation:
MonadTrans ListT | |
MonadTrans MaybeT | |
MonadTrans IdentityT | |
MonadTrans (ReaderT r) | |
MonadTrans (StateT s) | |
MonadTrans (StateT s) | |
MonadTrans (ExceptT e) | |
Error e => MonadTrans (ErrorT e) | |
Monoid w => MonadTrans (WriterT w) | |
Monoid w => MonadTrans (WriterT w) | |
Functor f => MonadTrans (Stream f) | |
Monoid w => MonadTrans (RWST r w s) | |
Monoid w => MonadTrans (RWST r w s) |