capability-0.2.0.0: Extensional capabilities and deriving combinators

Safe HaskellNone
LanguageHaskell2010

Capability.Stream

Contents

Description

Defines a capability for computations that produce a stream of values as part of their execution.

Programs producing streams of data are common. Examples: emitting events on input, or emitting events whenever certain conditions are observed. Streams are similar to Python generators.

The HasStream capability enables separating the logic responsible for emitting events from that responsible for collecting or handling them.

This can be thought of as a writer capability of a list of values HasWriter tag [v] with \x -> tell @tag [x] as a primitive operation. However, that implementation would be inefficient.

For example using the Stream instance, a producer defined using this capability can be consumed efficiently in a streaming fashion.

Synopsis

Interface

class Monad m => HasStream (tag :: k) (a :: *) (m :: * -> *) | tag m -> a where Source #

Streaming capability.

An instance does not need to fulfill any additional laws besides the monad laws.

Methods

yield_ :: Proxy# tag -> a -> m () Source #

For technical reasons, this method needs an extra proxy argument. You only need it if you are defining new instances of HasReader. Otherwise, you will want to use yield. See yield for more documentation.

Instances
(HasStream tag a m, MonadTrans t, Monad (t m)) => HasStream (tag :: k) a (Lift (t m)) Source #

Lift one layer in a monad transformer stack.

Note, that if the HasStream instance is based on HasState, then it is more efficient to apply Lift to the underlying state capability. E.g. you should favour

deriving (HasStream tag w) via
  StreamLog (Lift (SomeTrans (MonadState SomeStateMonad)))

over

deriving (HasStream tag w) via
  Lift (SomeTrans (StreamLog (MonadState SomeStateMonad)))
Instance details

Defined in Capability.Stream

Methods

yield_ :: Proxy# tag -> a -> Lift (t m) () Source #

HasState tag [a] m => HasStream (tag :: k) a (StreamStack m) Source # 
Instance details

Defined in Capability.Stream

Methods

yield_ :: Proxy# tag -> a -> StreamStack m () Source #

HasStream tag (DList a) m => HasStream (tag :: k) a (StreamDList m) Source #

This instance may seem a bit odd at first. All it does is wrap each yielded value in a single element difference list. How does re-yielding something else constitute a strategy for implementing HasStream in the first place? The answer is that difference lists form a monoid, which allows a second stragegy to be used which accumulates all yields in a single value, actually eliminating the HasStream constraint this time.

StreamLog below in fact does this, so the easiest way to fully eliminate the HasStream constraint as described above is:

deriving (HasStream tag w) via
  StreamDList (StreamLog (MonadState SomeStateMonad))
Instance details

Defined in Capability.Stream

Methods

yield_ :: Proxy# tag -> a -> StreamDList m () Source #

(Monoid w, HasState tag w m) => HasStream (tag :: k) w (StreamLog m) Source # 
Instance details

Defined in Capability.Stream

Methods

yield_ :: Proxy# tag -> w -> StreamLog m () Source #

Monad m => HasStream (tag :: k) a (Stream (Of a) m) Source # 
Instance details

Defined in Capability.Stream

Methods

yield_ :: Proxy# tag -> a -> Stream (Of a) m () Source #

(forall x. Coercible (m x) (t2 (t1 m) x), Monad m, HasStream tag a (t2 (t1 m))) => HasStream (tag :: k) a ((t2 :.: t1) m) Source #

Compose two accessors.

Instance details

Defined in Capability.Stream

Methods

yield_ :: Proxy# tag -> a -> (t2 :.: t1) m () Source #

yield :: forall tag a m. HasStream tag a m => a -> m () Source #

yield @tag a emits a in the stream capability tag.

Strategies

newtype StreamStack m (a :: *) Source #

Accumulate streamed values in a reverse order list.

Constructors

StreamStack (m a) 
Instances
HasState tag [a] m => HasStream (tag :: k) a (StreamStack m) Source # 
Instance details

Defined in Capability.Stream

Methods

yield_ :: Proxy# tag -> a -> StreamStack m () Source #

Monad m => Monad (StreamStack m) Source # 
Instance details

Defined in Capability.Stream

Methods

(>>=) :: StreamStack m a -> (a -> StreamStack m b) -> StreamStack m b #

(>>) :: StreamStack m a -> StreamStack m b -> StreamStack m b #

return :: a -> StreamStack m a #

fail :: String -> StreamStack m a #

Functor m => Functor (StreamStack m) Source # 
Instance details

Defined in Capability.Stream

Methods

fmap :: (a -> b) -> StreamStack m a -> StreamStack m b #

(<$) :: a -> StreamStack m b -> StreamStack m a #

Applicative m => Applicative (StreamStack m) Source # 
Instance details

Defined in Capability.Stream

Methods

pure :: a -> StreamStack m a #

(<*>) :: StreamStack m (a -> b) -> StreamStack m a -> StreamStack m b #

liftA2 :: (a -> b -> c) -> StreamStack m a -> StreamStack m b -> StreamStack m c #

(*>) :: StreamStack m a -> StreamStack m b -> StreamStack m b #

(<*) :: StreamStack m a -> StreamStack m b -> StreamStack m a #

MonadIO m => MonadIO (StreamStack m) Source # 
Instance details

Defined in Capability.Stream

Methods

liftIO :: IO a -> StreamStack m a #

PrimMonad m => PrimMonad (StreamStack m) Source # 
Instance details

Defined in Capability.Stream

Associated Types

type PrimState (StreamStack m) :: Type #

Methods

primitive :: (State# (PrimState (StreamStack m)) -> (#State# (PrimState (StreamStack m)), a#)) -> StreamStack m a #

type PrimState (StreamStack m) Source # 
Instance details

Defined in Capability.Stream

newtype StreamDList m (a :: *) Source #

Accumulate streamed values in forward order in a difference list.

Constructors

StreamDList (m a) 
Instances
HasStream tag (DList a) m => HasStream (tag :: k) a (StreamDList m) Source #

This instance may seem a bit odd at first. All it does is wrap each yielded value in a single element difference list. How does re-yielding something else constitute a strategy for implementing HasStream in the first place? The answer is that difference lists form a monoid, which allows a second stragegy to be used which accumulates all yields in a single value, actually eliminating the HasStream constraint this time.

StreamLog below in fact does this, so the easiest way to fully eliminate the HasStream constraint as described above is:

deriving (HasStream tag w) via
  StreamDList (StreamLog (MonadState SomeStateMonad))
Instance details

Defined in Capability.Stream

Methods

yield_ :: Proxy# tag -> a -> StreamDList m () Source #

Monad m => Monad (StreamDList m) Source # 
Instance details

Defined in Capability.Stream

Methods

(>>=) :: StreamDList m a -> (a -> StreamDList m b) -> StreamDList m b #

(>>) :: StreamDList m a -> StreamDList m b -> StreamDList m b #

return :: a -> StreamDList m a #

fail :: String -> StreamDList m a #

Functor m => Functor (StreamDList m) Source # 
Instance details

Defined in Capability.Stream

Methods

fmap :: (a -> b) -> StreamDList m a -> StreamDList m b #

(<$) :: a -> StreamDList m b -> StreamDList m a #

Applicative m => Applicative (StreamDList m) Source # 
Instance details

Defined in Capability.Stream

Methods

pure :: a -> StreamDList m a #

(<*>) :: StreamDList m (a -> b) -> StreamDList m a -> StreamDList m b #

liftA2 :: (a -> b -> c) -> StreamDList m a -> StreamDList m b -> StreamDList m c #

(*>) :: StreamDList m a -> StreamDList m b -> StreamDList m b #

(<*) :: StreamDList m a -> StreamDList m b -> StreamDList m a #

MonadIO m => MonadIO (StreamDList m) Source # 
Instance details

Defined in Capability.Stream

Methods

liftIO :: IO a -> StreamDList m a #

PrimMonad m => PrimMonad (StreamDList m) Source # 
Instance details

Defined in Capability.Stream

Associated Types

type PrimState (StreamDList m) :: Type #

Methods

primitive :: (State# (PrimState (StreamDList m)) -> (#State# (PrimState (StreamDList m)), a#)) -> StreamDList m a #

type PrimState (StreamDList m) Source # 
Instance details

Defined in Capability.Stream

newtype StreamLog m (a :: *) Source #

Accumulate streamed values with their own monoid.

Constructors

StreamLog (m a) 
Instances
(Monoid w, HasState tag w m) => HasStream (tag :: k) w (StreamLog m) Source # 
Instance details

Defined in Capability.Stream

Methods

yield_ :: Proxy# tag -> w -> StreamLog m () Source #

(Monoid w, HasState tag w m) => HasWriter (tag :: k) w (WriterLog m) Source # 
Instance details

Defined in Capability.Writer

Methods

writer_ :: Proxy# tag -> (a, w) -> WriterLog m a Source #

listen_ :: Proxy# tag -> WriterLog m a -> WriterLog m (a, w) Source #

pass_ :: Proxy# tag -> WriterLog m (a, w -> w) -> WriterLog m a Source #

Monad m => Monad (StreamLog m) Source # 
Instance details

Defined in Capability.Stream

Methods

(>>=) :: StreamLog m a -> (a -> StreamLog m b) -> StreamLog m b #

(>>) :: StreamLog m a -> StreamLog m b -> StreamLog m b #

return :: a -> StreamLog m a #

fail :: String -> StreamLog m a #

Functor m => Functor (StreamLog m) Source # 
Instance details

Defined in Capability.Stream

Methods

fmap :: (a -> b) -> StreamLog m a -> StreamLog m b #

(<$) :: a -> StreamLog m b -> StreamLog m a #

Applicative m => Applicative (StreamLog m) Source # 
Instance details

Defined in Capability.Stream

Methods

pure :: a -> StreamLog m a #

(<*>) :: StreamLog m (a -> b) -> StreamLog m a -> StreamLog m b #

liftA2 :: (a -> b -> c) -> StreamLog m a -> StreamLog m b -> StreamLog m c #

(*>) :: StreamLog m a -> StreamLog m b -> StreamLog m b #

(<*) :: StreamLog m a -> StreamLog m b -> StreamLog m a #

MonadIO m => MonadIO (StreamLog m) Source # 
Instance details

Defined in Capability.Stream

Methods

liftIO :: IO a -> StreamLog m a #

PrimMonad m => PrimMonad (StreamLog m) Source # 
Instance details

Defined in Capability.Stream

Associated Types

type PrimState (StreamLog m) :: Type #

Methods

primitive :: (State# (PrimState (StreamLog m)) -> (#State# (PrimState (StreamLog m)), a#)) -> StreamLog m a #

type PrimState (StreamLog m) Source # 
Instance details

Defined in Capability.Stream

Modifiers