Safe Haskell | Safe-Inferred |
---|---|
Language | GHC2021 |
A box is a product of a consumer and producer destructor.
Consumers and producers (committers and emitters) are paired in two ways:
- As two ends of a resource such as a file, or screen or queue; input to and output from.
- As the start and end of a computation pipeline.
Synopsis
- data Box m c e = Box {}
- type CoBox m a b = Codensity m (Box m a b)
- newtype CoBoxM m a b = CoBoxM {}
- bmap :: Monad m => (a' -> m (Maybe a)) -> (b -> m (Maybe b')) -> Box m a b -> Box m a' b'
- foistb :: (forall a. m a -> n a) -> Box m c e -> Box n c e
- glue :: Monad m => Committer m a -> Emitter m a -> m ()
- data Closure
- glue' :: Monad m => Committer m a -> Emitter m a -> m Closure
- glueN :: Monad m => Int -> Committer m a -> Emitter m a -> m ()
- glueES :: Monad m => s -> Committer m a -> Emitter (StateT s m) a -> m ()
- glueS :: Monad m => s -> Committer (StateT s m) a -> Emitter (StateT s m) a -> m ()
- fuse :: Monad m => (a -> m (Maybe b)) -> Box m b a -> m ()
- class Divap p where
- class Profunctor p => DecAlt p where
- cobox :: CoCommitter m a -> CoEmitter m b -> CoBox m a b
- seqBox :: Monad m => Box (StateT (Seq a) m) a a
Documentation
A Box is a product of a Committer
and an Emitter
.
Think of a box with an incoming arrow an outgoing arrow. And then make your pov ambiguous: are you looking at two wires from "inside a box"; or are you looking from "outside the box"; interacting with a black box object. Either way, it looks the same: it's a box.
And either way, one of the arrows, the Committer
, is contravariant and the other, the Emitter
is covariant. The combination is a profunctor.
Wrapper for the semigroupoid instance of a box continuation.
bmap :: Monad m => (a' -> m (Maybe a)) -> (b -> m (Maybe b')) -> Box m a b -> Box m a' b' Source #
A profunctor dimapMaybe
foistb :: (forall a. m a -> n a) -> Box m c e -> Box n c e Source #
Wrong kind signature for the FFunctor class
glue :: Monad m => Committer m a -> Emitter m a -> m () Source #
Connect an emitter directly to a committer of the same type.
>>>
glue showStdout <$|> qList [1..3]
1 2 3
Whether the committer or emitter closed the computation.
glue' :: Monad m => Committer m a -> Emitter m a -> m Closure Source #
Connect an emitter directly to a committer of the same type, returning whether the emitter or committer caused eventual closure.
>>>
glue' showStdout <$|> qList [1..3]
1 2 3 EmitterClosed
glueN :: Monad m => Int -> Committer m a -> Emitter m a -> m () Source #
Glues a committer and emitter, and takes n emits
>>>
glueN 3 <$> pure showStdout <*|> qList [1..]
1 2 3
Note that glueN counts the number of events passing across the connection and doesn't take into account post-transmission activity in the Committer, eg
>>>
glueN 4 (witherC (\x -> bool (pure Nothing) (pure (Just x)) (even x)) showStdout) <$|> qList [0..9]
0 2
glueES :: Monad m => s -> Committer m a -> Emitter (StateT s m) a -> m () Source #
Connect a Stateful emitter to a (non-stateful) committer of the same type, supplying initial state.
>>>
glueES 0 (showStdout) <$|> (takeE 2 <$> qList [1..3])
1 2
glueS :: Monad m => s -> Committer (StateT s m) a -> Emitter (StateT s m) a -> m () Source #
Connect a Stateful emitter to a (similarly-stateful) committer of the same type, supplying initial state.
>>>
glueS 0 (foist lift showStdout) <$|> (takeE 2 <$> qList [1..3])
1 2
fuse :: Monad m => (a -> m (Maybe b)) -> Box m b a -> m () Source #
Glue a Committer to an Emitter within a box.
fuse (pure . pure) == \(Box c e) -> glue c e
A command-line echoer
fuse (pure . Just . ("echo " <>)) (Box toStdout fromStdin)
class Profunctor p => DecAlt p where Source #
combines Decidable
and Alternative