-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Methods for composing monads. -- -- Methods for composing monads. -- -- The IO monad transformer solves the problem of combining two -- IO-performing monads, so that both may be transformed separately. -- -- A monad transformer can transform another monad, but if you have two -- monads both lacking a transformer, one can define an extended -- distributive law which allows a monad to arise - see -- Control.Monad.PlusMonad. @package MonadCompose @version 0.8.4.2 -- | 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 b)) (Either (Pair t a) (Pair t b)) assoc3 :: ((t, t1), t2) -> (t, (t1, t2)) assoc4 :: (t1, (t2, t)) -> ((t1, t2), t) void' :: A b t v -> A () t 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 Foreign.Storable.Storable (Control.Linear.Open p) instance Foreign.Storable.Storable Control.Linear.Semiclosed instance Foreign.Storable.Storable Control.Linear.Exclusive instance Data.Default.Class.Default a => Control.Category.Category (Control.Linear.A a) instance Data.Default.Class.Default a => Control.Arrow.Arrow (Control.Linear.A a) instance Data.Default.Class.Default a => Control.Arrow.ArrowChoice (Control.Linear.A a) instance Control.Linear.Openhandle Control.Linear.Exclusive instance Control.Linear.Openhandle (Control.Linear.Open p) instance Foreign.Storable.Storable Control.Linear.Blank instance (Foreign.Storable.Storable a, Foreign.Storable.Storable b) => Foreign.Storable.Storable (Control.Linear.Pair a b) instance Foreign.Storable.Storable GHC.IO.Handle.Types.Handle instance Foreign.Storable.Storable (Control.Linear.Pointer p s t) instance Control.Linear.Splittable Control.Linear.Nonlinear instance Control.Linear.Splittable Control.Linear.Focused instance Control.Linear.Weakening (Control.Linear.Pointer p Control.Linear.Focused t) instance Control.Linear.Weakening (Control.Linear.Pointer p Control.Linear.Nonlinear t) instance Control.Linear.Weakening (Control.Linear.Open p) -- | A construction combining two monads, based on the work of Luth and -- Ghani, "Composing Monads Using Coproducts." module Control.Monad.PlusMonad data Composition m n t -- | The following construction on two monads is a monad provided the two -- monads have extended distributive laws, defined below. type (::+) m n = Yoneda (Composition m n) -- | An extended distributive law allows one to permute two layers. -- -- Laws are: -- --
--   >>> join . T dist = dist . join :: TTS -> TST
--   
--   >>> TS join . dist . dist = dist :: TS -> TST
--   
class Dist n dist :: (Dist n, Applicative m) => n (m t) -> n (m (n t)) -- | Left and right maps... leftMap :: (Monad m, Functor n, Functor x) => (forall u. m u -> n u) -> (m ::+ x) t -> (n ::+ x) t rightMap :: (Monad x, Monad m, Functor n) => (forall u. m u -> n u) -> (x ::+ m) t -> (x ::+ n) t -- | Injections into the ::+ type. inl :: (Dist m, Dist n, Monad m, Monad n) => m t -> (m ::+ n) t inr :: (Dist m, Dist n, Monad m, Monad n) => n t -> (m ::+ n) t -- | If you have a ::+ over a monad, you can extract the underlying -- action. sym :: (Monad m) => (m ::+ m) t -> m t -- | ::+ is commutative. commute :: (Monad m, Monad n) => (m ::+ n) t -> (n ::+ m) t mapPlus :: (Monad m, Monad n, Functor m1, Functor n1) => (forall u. m u -> m1 u) -> (forall u. n u -> n1 u) -> (m ::+ n) t -> (m1 ::+ n1) t refl :: (MonadPlus m) => (m ::+ m) t -> m t -- | Example of an IO-performing ADT. data File t runFile :: File b -> FilePath -> IO b readLine :: File String instance GHC.Base.Functor Control.Monad.PlusMonad.File instance (GHC.Base.Functor m, GHC.Base.Functor n) => GHC.Base.Functor (Control.Monad.PlusMonad.Composition m n) instance Control.Monad.PlusMonad.Dist (Control.Monad.Trans.State.Lazy.StateT s Data.Functor.Identity.Identity) instance GHC.Base.Monoid s => Control.Monad.PlusMonad.Dist (Control.Monad.Trans.Writer.Lazy.WriterT s Data.Functor.Identity.Identity) instance Control.Monad.PlusMonad.Dist [] instance Control.Monad.PlusMonad.Dist GHC.Types.IO instance Control.Monad.PlusMonad.Dist Data.Functor.Identity.Identity instance Control.Monad.PlusMonad.Dist GHC.Base.Maybe instance Control.Monad.PlusMonad.Dist (Data.Either.Either t) instance Control.Monad.Trans.Error.Error e => Control.Monad.PlusMonad.Dist (Control.Monad.Trans.Error.ErrorT e Data.Functor.Identity.Identity) instance (Control.Monad.PlusMonad.Dist m, Control.Monad.PlusMonad.Dist n, GHC.Base.Monad m, GHC.Base.Monad n) => Control.Monad.PlusMonad.Dist (Control.Monad.PlusMonad.Composition m n) instance (Control.Monad.PlusMonad.Dist m, GHC.Base.Functor m) => Control.Monad.PlusMonad.Dist (Data.Functor.Yoneda.Yoneda m) instance (Control.Monad.PlusMonad.Dist m, Control.Monad.PlusMonad.Dist n, GHC.Base.Monad m, GHC.Base.Monad n) => GHC.Base.Monad (Control.Monad.PlusMonad.Composition m n) instance (Control.Monad.PlusMonad.Dist m, Control.Monad.PlusMonad.Dist n, GHC.Base.Monad m, GHC.Base.MonadPlus n) => GHC.Base.MonadPlus (Control.Monad.PlusMonad.Composition m n) instance (Control.Monad.PlusMonad.Dist m, Control.Monad.PlusMonad.Dist n, GHC.Base.Monad m, GHC.Base.Monad n) => GHC.Base.Applicative (Control.Monad.PlusMonad.Composition m n) instance (Control.Monad.PlusMonad.Dist m, Control.Monad.PlusMonad.Dist n, GHC.Base.Monad m, GHC.Base.MonadPlus n) => GHC.Base.Alternative (Control.Monad.PlusMonad.Composition m n) instance GHC.Base.Monad m => Control.Monad.Trans.Class.MonadTrans (Control.Monad.PlusMonad.Composition m) instance (Control.Monad.PlusMonad.Dist m, Control.Monad.PlusMonad.Dist n, GHC.Base.Monad m, GHC.Base.Monad n, Control.Monad.IO.Class.MonadIO n) => Control.Monad.IO.Class.MonadIO (Control.Monad.PlusMonad.Composition m n) instance GHC.Base.Monad Control.Monad.PlusMonad.File instance GHC.Base.Applicative Control.Monad.PlusMonad.File instance Control.Monad.PlusMonad.Dist Control.Monad.PlusMonad.File 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 Control.Monad.Lifter.Lifter (GHC.ST.ST GHC.Prim.RealWorld) GHC.Types.IO instance Control.Monad.Lifter.Lifter GHC.Types.IO GHC.Types.IO instance Control.Monad.Lifter.Lifter (GHC.ST.ST s) (GHC.ST.ST s) instance Control.Monad.Lifter.Lifter Data.Functor.Identity.Identity Data.Functor.Identity.Identity instance (Control.Monad.Trans.Class.MonadTrans n, GHC.Base.Monad x, Control.Monad.Lifter.Lifter m x) => Control.Monad.Lifter.Lifter m (n x) instance (GHC.Base.Monad x, Control.Monad.Morph.MFunctor m) => Control.Monad.Lifter.Lifter (m Data.Functor.Identity.Identity) (m x) 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 GHC.Base.Monad m => GHC.Base.Monad (Control.Monad.IOT.IOT m) instance GHC.Base.Monad m => GHC.Base.Applicative (Control.Monad.IOT.IOT m) instance GHC.Base.Monad m => GHC.Base.Functor (Control.Monad.IOT.IOT m) instance GHC.Base.Monad m => Control.Monad.IO.Class.MonadIO (Control.Monad.IOT.IOT m) instance Control.Monad.Trans.Class.MonadTrans Control.Monad.IOT.IOT instance Control.Monad.Morph.MFunctor Control.Monad.IOT.IOT instance Control.Monad.Morph.MMonad Control.Monad.IOT.IOT