-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | boxes -- -- A profunctor effect @package box @version 0.8.1 -- | Extra Codensity operators. module Box.Codensity -- | close a continuation -- --
--   >>> close $ glue showStdout <$> qList [1..3]
--   1
--   2
--   3
--   
close :: Codensity m (m r) -> m r -- | fmap then close over a Codensity -- --
--   >>> process (glue showStdout) (qList [1..3])
--   1
--   2
--   3
--   
process :: forall a m r. (a -> m r) -> Codensity m a -> m r -- | fmap then close over a Codensity -- --
--   >>> glue showStdout <$|> qList [1..3]
--   1
--   2
--   3
--   
(<$|>) :: forall a m r. (a -> m r) -> Codensity m a -> m r infixr 3 <$|> -- | apply to a continuation and close. -- --
--   >>> glue <$> (pure showStdout) <*|> qList [1..3]
--   1
--   2
--   3
--   
(<*|>) :: Codensity m (a -> m r) -> Codensity m a -> m r infixr 3 <*|> instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Control.Monad.Codensity.Codensity m a) instance (GHC.Base.Functor m, GHC.Base.Semigroup a, GHC.Base.Monoid a) => GHC.Base.Monoid (Control.Monad.Codensity.Codensity m a) module Box.Functor -- | An endofunctor in the category of endofunctors. -- -- Like MFunctor but without a Monad constraint. class FFunctor (h :: (Type -> Type) -> Type -> Type) foist :: FFunctor h => (forall x. f x -> g x) -> h f a -> h g a -- | Monadically Foldable class FoldableM (t :: (Type -> Type) -> Type -> Type) foldrM :: (FoldableM t, Monad m) => (a -> m b -> m b) -> m b -> t m a -> m b -- | emit module Box.Emitter -- | an Emitter emits values of type Maybe a. Source & -- Producer are also appropriate metaphors. -- -- An Emitter reaches into itself for the value to emit, where itself is -- an opaque thing from the pov of usage. -- --
--   >>> e = Emitter (pure (Just "I'm emitted"))
--   
--   >>> emit e
--   Just "I'm emitted"
--   
-- --
--   >>> emit mempty
--   Nothing
--   
newtype Emitter m a Emitter :: m (Maybe a) -> Emitter m a [emit] :: Emitter m a -> m (Maybe a) -- | An Emitter continuation. type CoEmitter m a = Codensity m (Emitter m a) -- | Collect emits into a list, and close on the first Nothing. -- --
--   >>> toListM <$|> qList [1..3]
--   [1,2,3]
--   
toListM :: Monad m => Emitter m a -> m [a] -- | A monadic Witherable -- --
--   >>> close $ toListM <$> witherE (\x -> bool (print x >> pure Nothing) (pure (Just x)) (even x)) <$> (qList [1..3])
--   1
--   3
--   [2]
--   
witherE :: Monad m => (a -> m (Maybe b)) -> Emitter m a -> Emitter m b -- | Read parse Emitter, returning the original text on error -- --
--   >>> process (toListM . readE) (qList ["1","2","3","four"]) :: IO [Either Text Int]
--   [Right 1,Right 2,Right 3,Left "four"]
--   
readE :: (Functor m, Read a) => Emitter m Text -> Emitter m (Either Text a) -- | Convert a list emitter to a (Stateful) element emitter. -- --
--   >>> import Control.Monad.State.Lazy
--   
--   >>> close $ flip runStateT [] . toListM . unlistE <$> (qList [[0..3],[5..7]])
--   ([0,1,2,3,5,6,7],[])
--   
unlistE :: Monad m => Emitter m [a] -> Emitter (StateT [a] m) a -- | Take n emits. -- --
--   >>> import Control.Monad.State.Lazy
--   
--   >>> close $ flip evalStateT 0 <$> toListM . takeE 4 <$> qList [0..]
--   [0,1,2,3]
--   
takeE :: Monad m => Int -> Emitter m a -> Emitter (StateT Int m) a -- | Take from an emitter until a predicate. -- --
--   >>> process (toListM . takeUntilE (==3)) (qList [0..])
--   [0,1,2]
--   
takeUntilE :: Monad m => (a -> Bool) -> Emitter m a -> Emitter m a -- | Pop from a State sequence. -- --
--   >>> import qualified Data.Sequence as Seq
--   
--   >>> import Control.Monad.State.Lazy (evalStateT)
--   
--   >>> flip evalStateT (Seq.fromList [1..3]) $ toListM pop
--   [1,2,3]
--   
pop :: Monad m => Emitter (StateT (Seq a) m) a instance Box.Functor.FFunctor Box.Emitter.Emitter instance GHC.Base.Functor m => GHC.Base.Functor (Box.Emitter.Emitter m) instance GHC.Base.Applicative m => GHC.Base.Applicative (Box.Emitter.Emitter m) instance GHC.Base.Monad m => GHC.Base.Monad (Box.Emitter.Emitter m) instance (GHC.Base.Monad m, GHC.Base.Alternative m) => GHC.Base.Alternative (Box.Emitter.Emitter m) instance (GHC.Base.Alternative m, GHC.Base.Monad m) => GHC.Base.MonadPlus (Box.Emitter.Emitter m) instance (GHC.Base.Alternative m, GHC.Base.Monad m) => GHC.Base.Semigroup (Box.Emitter.Emitter m a) instance (GHC.Base.Alternative m, GHC.Base.Monad m) => GHC.Base.Monoid (Box.Emitter.Emitter m a) instance Box.Functor.FoldableM Box.Emitter.Emitter -- | commit module Box.Committer -- | A Committer commits values of type a and signals success or -- otherwise. A Sink and a Consumer are some other metaphors for this. -- -- A Committer absorbs the value being committed; the value disappears -- into the opaque thing that is a Committer from the pov of usage. -- --
--   >>> commit toStdout "I'm committed!"
--   I'm committed!
--   True
--   
newtype Committer m a Committer :: (a -> m Bool) -> Committer m a [commit] :: Committer m a -> a -> m Bool -- | Committer continuation. type CoCommitter m a = Codensity m (Committer m a) -- | A monadic Witherable -- --
--   >>> glue (witherC (\x -> pure $ bool Nothing (Just x) (even x)) showStdout) <$|> qList [0..5]
--   0
--   2
--   4
--   
witherC :: Monad m => (b -> m (Maybe a)) -> Committer m a -> Committer m b -- | Convert a committer to be a list committer. Think mconcat. -- --
--   >>> glue showStdout <$|> qList [[1..3]]
--   [1,2,3]
--   
-- --
--   >>> glue (listC showStdout) <$|> qList [[1..3]]
--   1
--   2
--   3
--   
listC :: Monad m => Committer m a -> Committer m [a] -- | Push to a state sequence. -- --
--   >>> import Control.Monad.State.Lazy
--   
--   >>> import qualified Data.Sequence as Seq
--   
--   >>> flip execStateT Seq.empty . glue push . foist lift <$|> qList [1..3]
--   fromList [1,2,3]
--   
push :: Monad m => Committer (StateT (Seq a) m) a instance Box.Functor.FFunctor Box.Committer.Committer instance GHC.Base.Applicative m => GHC.Base.Semigroup (Box.Committer.Committer m a) instance GHC.Base.Applicative m => GHC.Base.Monoid (Box.Committer.Committer m a) instance Data.Functor.Contravariant.Contravariant (Box.Committer.Committer m) instance GHC.Base.Applicative m => Data.Functor.Contravariant.Divisible.Divisible (Box.Committer.Committer m) instance GHC.Base.Applicative m => Data.Functor.Contravariant.Divisible.Decidable (Box.Committer.Committer m) -- | A box is something that commits and emits module Box.Box -- | 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. data Box m c e Box :: Committer m c -> Emitter m e -> Box m c e [committer] :: Box m c e -> Committer m c [emitter] :: Box m c e -> Emitter m e -- | A box continuation type CoBox m a b = Codensity m (Box m a b) -- | Wrapper for the semigroupoid instance of a box continuation. newtype CoBoxM m a b CoBoxM :: Codensity m (Box m a b) -> CoBoxM m a b [uncobox] :: CoBoxM m a b -> Codensity m (Box m a b) -- | A profunctor dimapMaybe bmap :: Monad m => (a' -> m (Maybe a)) -> (b -> m (Maybe b')) -> Box m a b -> Box m a' b' -- | Wrong kind signature for the FFunctor class foistb :: (forall a. m a -> n a) -> Box m c e -> Box n c e -- | Connect an emitter directly to a committer of the same type. -- --
--   >>> glue showStdout <$|> qList [1..3]
--   1
--   2
--   3
--   
glue :: Monad m => Committer m a -> Emitter m a -> m () -- | 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
--   
glueN :: Monad m => Int -> Committer m a -> Emitter m a -> m () -- | 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)
--   
fuse :: Monad m => (a -> m (Maybe b)) -> Box m b a -> m () -- | combines divide conquer and liftA2 pure class Divap p divap :: Divap p => (a -> (b, c)) -> ((d, e) -> f) -> p b d -> p c e -> p a f conpur :: Divap p => a -> p b a -- | combines Decidable and Alternative class Profunctor p => DecAlt p choice :: DecAlt p => (a -> Either b c) -> (Either d e -> f) -> p b d -> p c e -> p a f loss :: DecAlt p => p Void b -- | Construct a CoBox -- --
--   cobox = Box <$> c <*> e
--   
-- --
--   >>> fuse (pure . Just . ("show: " <>) . pack . show) <$|> (cobox (pure toStdout) (qList [1..3]))
--   show: 1
--   show: 2
--   show: 3
--   
cobox :: CoCommitter m a -> CoEmitter m b -> CoBox m a b -- | State monad queue. seqBox :: Monad m => Box (StateT (Seq a) m) a a instance GHC.Base.Monad m => Data.Semigroupoid.Semigroupoid (Box.Box.CoBoxM m) instance (GHC.Base.Monad m, GHC.Base.Alternative m) => Box.Box.DecAlt (Box.Box.Box m) instance GHC.Base.Applicative m => Box.Box.Divap (Box.Box.Box m) instance GHC.Base.Functor m => Data.Profunctor.Unsafe.Profunctor (Box.Box.Box m) instance (GHC.Base.Alternative m, GHC.Base.Monad m) => GHC.Base.Semigroup (Box.Box.Box m c e) instance (GHC.Base.Alternative m, GHC.Base.Monad m) => GHC.Base.Monoid (Box.Box.Box m c e) -- | STM Queues, based originally on pipes-concurrency module Box.Queue -- | Queue specifies how messages are queued data Queue a Unbounded :: Queue a Bounded :: Int -> Queue a Single :: Queue a Latest :: a -> Queue a Newest :: Int -> Queue a New :: Queue a -- | Create an unbounded queue, returning the result from the Committer -- action. -- --
--   >>> queueL New (\c -> glue c <$|> qList [1..3]) toListM
--   
queueL :: MonadConc m => Queue a -> (Committer m a -> m l) -> (Emitter m a -> m r) -> m l -- | Create an unbounded queue, returning the result from the Emitter -- action. -- --
--   >>> queueR New (\c -> glue c <$|> qList [1..3]) toListM
--   [3]
--   
queueR :: MonadConc m => Queue a -> (Committer m a -> m l) -> (Emitter m a -> m r) -> m r -- | Create an unbounded queue, returning both results. -- --
--   >>> queue Unbounded (\c -> glue c <$|> qList [1..3]) toListM
--   ((),[1,2,3])
--   
queue :: MonadConc m => Queue a -> (Committer m a -> m l) -> (Emitter m a -> m r) -> m (l, r) -- | Turn a box action into a box continuation fromAction :: MonadConc m => (Box m a b -> m r) -> CoBox m b a -- | Hook a committer action to a queue, creating an emitter continuation. emitQ :: MonadConc m => Queue a -> (Committer m a -> m r) -> CoEmitter m a -- | Hook a committer action to a queue, creating an emitter continuation. commitQ :: MonadConc m => Queue a -> (Emitter m a -> m r) -> CoCommitter m a -- | Various ways to connect things up. module Box.Connectors -- | Queue a list. -- --
--   >>> pushList <$|> qList [1,2,3]
--   [1,2,3]
--   
qList :: MonadConc m => [a] -> CoEmitter m a -- | Directly supply a list to a committer action, via pop. -- --
--   >>> popList [1..3] showStdout
--   1
--   2
--   3
--   
popList :: Monad m => [a] -> Committer m a -> m () -- | Push an Emitter into a list, via push. -- --
--   >>> pushList <$|> qList [1..3]
--   [1,2,3]
--   
pushList :: Monad m => Emitter m a -> m [a] -- | Push an Emitter into a list, finitely. -- --
--   >>> pushListN 2 <$|> qList [1..3]
--   [1,2]
--   
pushListN :: Monad m => Int -> Emitter m a -> m [a] -- | Create a finite Committer. -- --
--   >>> glue <$> sink 2 print <*|> qList [1..3]
--   1
--   2
--   
sink :: MonadConc m => Int -> (a -> m ()) -> CoCommitter m a -- | Create a finite Emitter. -- --
--   >>> glue toStdout <$|> source 2 (pure "hi")
--   hi
--   hi
--   
source :: MonadConc m => Int -> m a -> CoEmitter m a -- | Glues an emitter to a committer, then resupplies the emitter. -- --
--   >>> (c1,l1) <- refCommitter :: IO (Committer IO Int, IO [Int])
--   
--   >>> close $ toListM <$> (forkEmit <$> (qList [1..3]) <*> pure c1)
--   [1,2,3]
--   
-- --
--   >>> l1
--   [1,2,3]
--   
forkEmit :: Monad m => Emitter m a -> Committer m a -> Emitter m a -- | Buffer a committer. bufferCommitter :: MonadConc m => Committer m a -> CoCommitter m a -- | Buffer an emitter. bufferEmitter :: MonadConc m => Emitter m a -> CoEmitter m a -- | Concurrently run two emitters. -- -- This differs to (<>), which is left-biased. -- -- Note that functions such as toListM, which complete on the first -- Nothing emitted, will not work as expected. -- --
--   >>> close $ (fmap toListM) (join $ concurrentE Single <$> qList [1..3] <*> qList [5..9])
--   [1,2,3]
--   
-- -- In the code below, the ordering is non-deterministic. -- --
--   (c,l) <- refCommitter :: IO (Committer IO Int, IO [Int])
--   close $ glue c <$> (join $ concurrentE Single <$> qList [1..30] <*> qList [40..60])
--   
concurrentE :: MonadConc f => Queue a -> Emitter f a -> Emitter f a -> CoEmitter f a -- | Concurrently run two committers. -- --
--   >>> import Data.Functor.Contravariant
--   
--   >>> import Data.Text (pack)
--   
--   >>> cFast = witherC (\b -> pure (Just b)) . contramap ("fast: " <>) $ toStdout
--   
--   >>> cSlow = witherC (\b -> sleep 0.1 >> pure (Just b)) . contramap ("slow: " <>) $ toStdout
--   
--   >>> close $ (popList ((pack . show) <$> [1..3]) <$> (concurrentC Unbounded cFast cSlow)) <> pure (sleep 1)
--   fast: 1
--   fast: 2
--   fast: 3
--   slow: 1
--   slow: 2
--   slow: 3
--   
concurrentC :: MonadConc m => Queue a -> Committer m a -> Committer m a -> CoCommitter m a -- | IO effects module Box.IO -- | Emit text from stdin -- --
--   λ> emit fromStdin
--   hello
--   Just "hello"
--   
fromStdin :: Emitter IO Text -- | Commit to stdout -- --
--   >>> commit toStdout ("I'm committed!" :: Text)
--   I'm committed!
--   True
--   
toStdout :: Committer IO Text -- | Finite console emitter -- --
--   λ> toListM <$|> fromStdinN 2
--   hello
--   hello again
--   ["hello","hello again"]
--   
fromStdinN :: Int -> CoEmitter IO Text -- | Finite console committer -- --
--   >>> glue <$> contramap (pack . show) <$> (toStdoutN 2) <*|> qList [1..3]
--   1
--   2
--   
toStdoutN :: Int -> CoCommitter IO Text -- | Read from console, throwing away read errors -- -- λ> glueN 2 showStdout (readStdin :: Emitter IO Int) 1 1 hippo 2 readStdin :: Read a => Emitter IO a -- | Show to stdout -- --
--   >>> glue showStdout <$|> qList [1..3]
--   1
--   2
--   3
--   
showStdout :: Show a => Committer IO a -- | Emits lines of Text from a handle. handleE :: Handle -> Emitter IO Text -- | Commit lines of Text to a handle. handleC :: Handle -> Committer IO Text -- | Commit to an IORef -- --
--   >>> (c1,l1) <- refCommitter :: IO (Committer IO Int, IO [Int])
--   
--   >>> glue c1 <$|> qList [1..3]
--   
--   >>> l1
--   [1,2,3]
--   
refCommitter :: MonadConc m => m (Committer m a, m [a]) -- | Emit from a list IORef -- --
--   >>> e <- refEmitter [1..3]
--   
--   >>> toListM e
--   [1,2,3]
--   
refEmitter :: MonadConc m => [a] -> m (Emitter m a) -- | Emit lines of Text from a file. fileE :: FilePath -> CoEmitter IO Text -- | Commit lines of Text to a file. fileWriteC :: FilePath -> CoCommitter IO Text -- | Commit lines of Text, appending to a file. fileAppendC :: FilePath -> CoCommitter IO Text -- | Timing effects. module Box.Time -- | Sleep for x seconds. sleep :: MonadConc m => Double -> m () -- | A value with a UTCTime annotation. data Stamped a Stamped :: !UTCTime -> !a -> Stamped a [stamp] :: Stamped a -> !UTCTime [value] :: Stamped a -> !a -- | Add the current time stampNow :: (MonadConc m, MonadIO m) => a -> m (LocalTime, a) -- | Add the current time stamp. -- --
--   > process (toListM . stampE) (qList [1..3])
--   [(2022-02-09 01:18:00.293883,1),(2022-02-09 01:18:00.293899,2),(2022-02-09 01:18:00.293903,3)]
--   
stampE :: (MonadConc m, MonadIO m) => Emitter m a -> Emitter m (LocalTime, a) -- | Wait s seconds before emitting emitIn :: Emitter IO (Double, a) -> Emitter IO a -- | Replay a stamped emitter, adjusting the speed of the replay. -- --
--   > glueN 4 showStdout $| replay 1 (Emitter $ sleep 0.1 >> Just $ stampNow ())
--   
replay :: Double -> Emitter IO (LocalTime, a) -> CoEmitter IO a instance GHC.Read.Read a => GHC.Read.Read (Box.Time.Stamped a) instance GHC.Show.Show a => GHC.Show.Show (Box.Time.Stamped a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Box.Time.Stamped a) -- | A profunctor effect -- -- “Boxes are surprisingly bulky. Discard or recycle the box your cell -- phone comes in as soon as you unpack it. You don’t need the manual or -- the CD that comes with it either. You’ll figure out the applications -- you need through using it.” — Marie Kondo module Box