-- 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: -- -- -- -- 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)