-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Methods for composing monads.
--
@package MonadCompose
@version 0.8.3.1
-- | A linear type-based I/O system a la Clean - including a "safe C" (like
-- Cyclone).
--
-- This is an alternative to composing monads - one can decompose them
-- into their corresponding comonads, with linear operations for
-- manipulating them. (See Kieburtz,
-- http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.46.5169&rep=rep1&type=pdf)
module Control.Linear
-- | Values representing the real world.
data St
-- | Linear computations are arrows over linear data, but monads over
-- nonlinear data.
data A t u v
data Blank
data Pair t u
type Fn t u = A () (Pair t St) (Pair u St)
-- | Monadic bind (for nonlinear data).
(>>==) :: A t t1 t3 -> (t -> A t2 t3 v) -> A t2 t1 v
-- | Monadic return
rtn :: t -> A t v v
-- | This setup is from
-- http://cs.ioc.ee/~tarmo/tsem11/jeltsch1602-slides.pdf
--
-- It implements some of
-- http://pauillac.inria.fr/~fpottier/slides/fpottier-2007-05-linear-bestiary.pdf
run :: A a St St -> IO a
bimap :: A t3 t t2 -> A t4 t1 u -> A (t3, t4) (Pair t t1) (Pair t2 u)
assoc1 :: A () (Pair (Pair t t1) u) (Pair t (Pair t1 u))
assoc2 :: A () (Pair t (Pair u1 u)) (Pair (Pair t u1) u)
drop1 :: A () (Pair Blank v) v
drop2 :: A () (Pair v Blank) v
undrop1 :: A () u (Pair Blank u)
undrop2 :: A () t (Pair t Blank)
swap :: A () (Pair u t) (Pair t u)
apply :: A t (Pair (A t t1 v) t1) v
curry :: A t (Pair t1 u) v -> A () t1 (A t u v)
distr :: A () (Pair t (Either a a1)) (Either (Pair t a) (Pair t a1))
assoc3 :: ((t, t1), t2) -> (t, (t1, t2))
assoc4 :: (t1, (t2, t)) -> ((t1, t2), t)
void' :: A t t1 v -> A () t1 v
bimap' :: A () t u -> A () v w -> A () (Pair t v) (Pair u w)
data Exclusive
data Semiclosed
data Open p
data Placeholder
Placeholder :: Placeholder
open :: FilePath -> IOMode -> A () St (Pair Exclusive St)
getStdin :: A () Blank (Open p)
getStdout :: A () Blank (Open p)
getStderr :: A () Blank (Open p)
close :: A () (Pair Exclusive St) St
close1 :: A () (Pair Semiclosed St) St
fileSize :: Openhandle h => A Integer (Pair h St) (Pair h St)
setFileSize :: Openhandle t => Integer -> A () (Pair t St) (Pair t St)
eof :: Openhandle h => A Bool (Pair h St) (Pair h St)
seek :: Openhandle t => SeekMode -> Integer -> A () (Pair t St) (Pair t St)
tell :: Openhandle h => A Integer (Pair h St) (Pair h St)
char :: Openhandle h => A Char (Pair h St) (Pair h St)
line :: Openhandle h => A String (Pair h St) (Pair h St)
lookahead :: Openhandle h => A Char (Pair h St) (Pair h St)
contents :: A String (Pair Exclusive St) (Pair Semiclosed St)
putC :: Openhandle t => Char -> A () (Pair t St) (Pair t St)
putS :: Openhandle t => String -> A () (Pair t St) (Pair t St)
random :: Random t => (t, t) -> A t Blank Blank
data Pointer p s t
-- | Pointers can be linear, nonlinear, or focused. There are the following
-- tradeoffs:
--
--
-- - Linear pointers support strong update, but can only be split under
-- focusing.
-- - Nonlinear pointers can be split, but do not support strong
-- update.
--
--
-- Placeholders classify pointers that either point to junk or to data
-- that is not allowed to be used (to maintain linearity).
data Linear
Linear :: Linear
data Nonlinear
Nonlinear :: Nonlinear
data Focused
Focused :: Focused
-- | With the Fix constructor, I can build data structures of linear data.
data Fix f
In :: (f (Fix f)) -> Fix f
fixInj1 :: Pointer p s (Fix f) -> Pointer p s (f (Fix f))
fixInj2 :: Pointer p s (f (Fix f)) -> Pointer p s (Fix f)
class Weakening t
weakening :: Weakening t => A () (Pair t St) St
contraction :: A () (Pointer Nonlinear s t) (Pair (Pointer Nonlinear s t) (Pointer Nonlinear s t))
-- | Allocate a new linear block (containing junk), Use poke' to
-- initialize it.
new :: Storable t => A () St (Pair (Pointer p Placeholder t) St)
-- | Use peek' to take ownership of the contents of a block before
-- freeing it.
free :: A () (Pair (Pointer p2 Placeholder t) St) St
-- | Split a pointer to a pair, into a pair of pointers.
split :: (Storable t, Storable u, Splittable s) => A () (Pointer p s (Pair t u)) (Pair (Pointer p s t) (Pointer p s u))
ptrSwap :: Storable t => Fn (Pair (Pointer p s t) t) (Pair (Pointer p s t) t)
-- | Focusing on a pointer.
--
-- Temporarily turns a linear pointer into a focused pointer. I get the
-- linear pointer back after all copies have been surrendered (with
-- weakening).
focus :: (forall p. A a (Pair (Pointer p Focused t) u) v) -> A a (Pair (Pointer p s t) u) (Pair (Pointer p s t) v)
-- | Focusing on a handle.
focusHdl :: (forall p. A a (Pair (Open p) t) u) -> A a (Pair Exclusive t) (Pair Exclusive u)
-- | Take the data out of a block, making it a placeholder.
peek' :: Storable t => Fn (Pointer p Linear t) (Pair (Pointer p Placeholder t) t)
-- | The reverse operation.
poke' :: Storable t => Fn (Pair (Pointer p Placeholder t) t) (Pointer p Linear t)
-- | A placeholder block can change its type.
changeType :: (Storable t, Storable u) => A () (Pointer p Placeholder t) (Pointer p Placeholder u)
-- | Allocate a nonlinear pointer.
newNonlinear :: Storable t => t -> A () Blank (Pointer p Nonlinear t)
peek1 :: Storable t => A t (Pair (Pointer Nonlinear s t) St) (Pair (Pointer Nonlinear s t) St)
poke1 :: Storable t => t -> Fn (Pointer p s t) (Pointer p s t)
-- | Duplicate the world state. This is interpreted as creating a thread.
fork :: A () St (Pair St St)
-- | Sync together two world states.
join' :: A () (Pair St St) St
helloWorld :: A () St St
printStuff :: A () St St
concurrent :: A () St St
instance Storable Exclusive
instance Storable Semiclosed
instance Storable (Open p)
instance Weakening (Open p)
instance Weakening (Pointer p Nonlinear t)
instance Weakening (Pointer p Focused t)
instance Splittable Focused
instance Splittable Nonlinear
instance Storable (Pointer p s t)
instance Storable Handle
instance (Storable a, Storable b) => Storable (Pair a b)
instance Storable Blank
instance Openhandle (Open p)
instance Openhandle Exclusive
instance Default a => ArrowChoice (A a)
instance Default a => Arrow (A a)
instance Default a => Category (A a)
-- | The Plus monad - a free combination of monads. This is very similar to
-- coproducts, but not quite the same.
--
-- Coproducts are due to Luth and Ghani, "Composing Monads Using
-- Coproducts,"
-- http://www.informatik.uni-bremen.de/~cxl/papers/icfp02.pdf
module Control.Monad.PlusMonad
newtype (::+) m n t
Plus :: (forall x. MonadPlus x => (forall u. m u -> x u) -> (forall u. n u -> x u) -> x t) -> (::+) m n t
unPlus :: (::+) m n t -> forall x. MonadPlus x => (forall u. m u -> x u) -> (forall u. n u -> x u) -> x t
inl :: m t -> (::+) m n t
inr :: n t -> (::+) m n t
mapPlus :: (forall t. m t -> m1 t) -> (forall t. n t -> n1 t) -> (m ::+ n) t -> (m1 ::+ n1) t
comm :: (m ::+ n) t -> (n ::+ m) t
assoc :: (::+) ((::+) m n) n1 t -> (::+) m ((::+) n n1) t
assoc1 :: (::+) t ((::+) n1 n) t1 -> (::+) ((::+) t n1) n t1
cancelLeft :: MonadPlus t => (::+) Identity t t1 -> t t1
cancelRight :: MonadPlus t => (::+) t Identity t1 -> t t1
refl :: MonadPlus t => (::+) t t t1 -> t t1
-- | Distributivity with monad products.
distr :: (::+) (Product m1 h) (Product n1 h1) a -> Product ((::+) m1 n1) ((::+) h h1) a
instance [safe] MonadPlus m => MMonad ((::+) m)
instance [safe] MFunctor ((::+) m)
instance [safe] MonadTrans ((::+) m)
instance [safe] Alternative (m ::+ n)
instance [safe] MonadPlus (m ::+ n)
instance [safe] Applicative (m ::+ n)
instance [safe] Functor (m ::+ n)
instance [safe] Monad (m ::+ n)
module Control.Monad.Lifter
-- | An automatic lifter. The idea of automatic lifting is due to Dan
-- Piponi.
class Lifter m n
lf :: Lifter m n => m t -> n t
instance [overlap ok] (Monad x, MFunctor m) => Lifter (m Identity) (m x)
instance [overlap ok] (MonadTrans n, Monad x, Lifter m x) => Lifter m (n x)
instance [overlap ok] Lifter m (m ::+ n)
instance [overlap ok] Lifter Identity Identity
instance [overlap ok] Lifter (ST s) (ST s)
instance [overlap ok] Lifter IO IO
instance [overlap ok] Lifter (ST RealWorld) IO
module Control.Monad.Distributive
swap :: (t1, t) -> (t, t1)
class MonadTrans m => Takeout m y | m -> y
takeout :: (Takeout m y, Monad n) => m n t -> m Identity (n (y t))
combine :: (Takeout m y, Monad x) => y t -> m x t
-- | The opposite of takeout.
putin :: (MonadTrans t1, MonadTrans t, MFunctor t1, MFunctor t, Monad (t1 n), Monad (t (t1 n)), Monad (t n), Monad n) => t n (t1 Identity b) -> t (t1 n) b
putin1 :: (MonadTrans t, MFunctor t, Monad (t n), Monad n) => t Identity (n b) -> t n b
-- | Transformers that distribute over one another.
--
-- For reorganizing a monad stack.
class Leftdistr m
ldist :: (Leftdistr m, Monad (n x), Monad x) => m (n x) t -> n x (m Identity t)
class Rightdistr m
rdist :: (Rightdistr m, Monad (n Identity), Monad (n x), MonadTrans n, MFunctor n, Monad x) => n Identity (m x t) -> m (n x) t
-- | Left distributivity of a monad transformer.
ldist' :: (Leftdistr t1, MonadTrans t1, MonadTrans t, MFunctor t1, MFunctor t, Monad (t1 n), Monad (t (t1 n)), Monad (t n), Monad n) => t1 (t n) b -> t (t1 n) b
-- | Right distributivity.
rdist' :: (Takeout n y, Rightdistr m, MonadTrans m, MFunctor n, Monad (n Identity), Monad (n x), Monad (m (n x)), Monad (m x), Monad x) => n (m x) b -> m (n x) b
instance [safe] Rightdistr (ReaderT v)
instance [safe] Rightdistr (StateT v)
instance [safe] Rightdistr (StateT v)
instance [safe] Leftdistr ListT
instance [safe] Monoid x => Leftdistr (WriterT x)
instance [safe] Error t => Leftdistr (ErrorT t)
instance [safe] Monoid w => Takeout (WriterT w) ((,) w)
instance [safe] Takeout (ReaderT r) Identity
instance [safe] Takeout (StateT s) ((,) s)
instance [safe] Takeout (StateT s) ((,) s)
module Control.Monad.IOT
-- | An IO monad transformer.
--
-- IOT cannot be unwrapped in the usual way -- the monad inside it
-- has to be unwrapped. This is done using run, and hoist
-- from mmorph.
--
-- Most of the safety of the IO monad is ensured statically. However, to
-- ensure that the same RealWorld token is not used multiple times, a
-- runtime check is necessary. Among the alternatives that perform I/O,
-- the first alternative forced by a concatenation of hoists will
-- contain a result, and subsequent alternatives will be errors.
--
-- Therefore, a concatenation of hoists out of a monad defines
-- at most one path of RealWorld token use. Here is an example using the
-- binary tree monad:
--
--
-- >>> let io :: IOT Tree () = lift (Node (Leaf 1) (Leaf 2)) >>= liftIO . print
--
--
--
-- >>> run $ hoist (\(Node (Leaf x) _) -> Identity x) io
-- 1
--
--
--
-- >>> run $ hoist (\(Node _ (Leaf x)) -> Identity x) io
-- 2
--
--
--
-- >>> run $ hoist (\(Node (Leaf _) (Leaf x)) -> Identity x) io
-- 1
-- *** Exception: IOT: double RealWorld use
--
data IOT m t
-- | Run an IOT yielding an IO computation. The Identity monad is a
-- trivial wrapper around IO.
run :: IOT Identity t -> IO t
instance MMonad IOT
instance MFunctor IOT
instance MonadTrans IOT
instance Monad m => MonadIO (IOT m)
instance Monad m => Functor (IOT m)
instance Monad m => Applicative (IOT m)
instance Monad m => Monad (IOT m)