-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Methods for composing monads. -- @package MonadCompose @version 0.8.1.0 -- | A linear type-based I/O system a la Clean. -- -- 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 t2 t t3 -> (t2 -> A t1 t3 v) -> A t1 t 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)) void' :: A t1 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 :: A StdGen Blank Blank data Pointer p s t -- | Pointers can be freeable, foreign, 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 Freeable Freeable :: Freeable data Foreign Foreign :: Foreign 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 () t Blank contraction :: Copyable s => A () (Pointer p s t) (Pair (Pointer p s t) (Pointer p s t)) -- | Allocate a new freeable block (containing junk), Use poke' to -- initialize it. new :: Storable t => A () Blank (Pointer p Placeholder t) -- | Use peek' to take ownership of the contents of a block before -- freeing it. free :: A () (Pointer p2 Placeholder t) Blank -- | Split a pointer to a pair, into a pair of pointers. split :: (Storable t, Storable u, Copyable 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 freeable pointer into a focused pointer. I get the -- freeable pointer back after all copies have been surrendered (with -- weakening). focus :: (forall p. A a (Pair (Pointer p Focused t) u) (Pair v St)) -> A a (Pair (Pointer p2 s t) u) (Pair (Pair (Pointer p2 s t) v) St) -- | 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 Freeable t) (Pair (Pointer p Placeholder t) t) -- | The reverse operation. poke' :: Storable t => Fn (Pair (Pointer p Placeholder t) t) (Pointer p Freeable t) -- | A placeholder block can change its type. changeType :: (Storable t, Storable u) => A () (Pointer p Placeholder t) (Pointer p Placeholder u) -- | Allocate a Foreign pointer. newForeign :: Storable t => t -> A () Blank (Pointer p Foreign t) peek1 :: (Storable t, Copyable s) => A t (Pair (Pointer p s t) St) (Pair (Pointer p s t) St) poke1 :: Storable t => t -> Fn (Pointer p s t) (Pointer p s t) instance Storable Exclusive instance Storable Semiclosed instance Storable (Open p) instance Weakening (Open p) instance Weakening (Pointer p Foreign t) instance Weakening (Pointer p Focused t) instance Copyable Foreign instance Copyable Focused 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 MonadPlus m => MMonad ((::+) m) instance MFunctor ((::+) m) instance MonadTrans ((::+) m) instance Alternative (m ::+ n) instance MonadPlus (m ::+ n) instance Applicative (m ::+ n) instance Functor (m ::+ n) instance 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, Takeout m y, Rightdistr 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 Rightdistr (ReaderT v) instance Rightdistr (StateT v) instance Rightdistr (StateT v) instance Leftdistr ListT instance Monoid x => Leftdistr (WriterT x) instance Error t => Leftdistr (ErrorT t) instance Leftdistr MaybeT instance Monoid w => Takeout (WriterT w) ((,) w) instance Takeout (ReaderT r) Identity instance Takeout (StateT s) ((,) s) instance Takeout (StateT s) ((,) s) module Control.Monad.IOT -- | An IO monad transformer. -- -- I can't run IOT. Instead, I run the monad inside it. This is -- done using run, and hoist from mmorph. -- -- The combination is only a monad if the parameter monad isn't -- nondeterministic. IOT Maybe and IOT State are monads, but IOT [] and -- IOT Cont are not. -- -- Should be integrated with STT. data IOT m t -- | Run an IOT. run :: IOT Identity t -> IO t instance MFunctor IOT instance MMonad 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)