monad-resumption (empty) → 0.1.0.1
raw patch · 6 files changed
+166/−0 lines, 6 filesdep +basedep +mtldep +transformerssetup-changed
Dependencies added: base, mtl, transformers
Files
- Control/Monad/Resumption.hs +51/−0
- Control/Monad/Resumption/Reactive.hs +52/−0
- LICENSE +30/−0
- README.md +4/−0
- Setup.hs +2/−0
- monad-resumption.cabal +27/−0
+ Control/Monad/Resumption.hs view
@@ -0,0 +1,51 @@+-- | A resumption monad transformer, based on the formulation in the article+-- <http://people.cs.missouri.edu/~harrisonwl/drafts/CheapThreads.pdf Cheap (But Functional) Threads>+-- by William L. Harrison and Adam Procter.+module Control.Monad.Resumption where++import Control.Monad+import Control.Monad.Trans+import Control.Applicative+import Control.Monad.IO.Class++-- | Resumption monad transformer.+newtype ResT m a = ResT { deResT :: m (Either a (ResT m a)) }++-- | Runs a resumptive computation to exhaustion, producing its final return+-- value.+runResT :: (Monad m) => ResT m a -> m a+runResT (ResT m) = do+ x <- m+ case x of + Left val -> return val+ Right m -> runResT m++instance Monad m => Monad (ResT m) where+ return x = ResT $ return $ Left x+ ResT m >>= f = ResT $ do + x <- m + case x of+ Left val -> return $ Right $ f val + Right res -> return $ Right $ res >>= f ++instance MonadTrans ResT where+ lift m = ResT (m >>= return . Left)+++instance Monad m => Functor (ResT m) where+ fmap f (ResT m) = ResT $ do+ x <- m+ case x of+ Left val -> return $ Left $ f val+ Right res -> return $ Right $ res >>= return . f++instance Monad m => Applicative (ResT m) where+ pure = return+ (<*>) = ap+ +instance MonadIO m => MonadIO (ResT m) where+ liftIO = lift . liftIO++-- | Waits until the next tick.+tick :: Monad m => ResT m ()+tick = ResT (return (Right (return ())))
+ Control/Monad/Resumption/Reactive.hs view
@@ -0,0 +1,52 @@+-- | A reactive resumption monad transforemer, based on the formulation in+-- the article <http://people.cs.missouri.edu/~harrisonwl/drafts/CheapThreads.pdf Cheap (But Functional) Threads>+-- by William L. Harrison and Adam Procter.+module Control.Monad.Resumption.Reactive where++import Control.Monad+import Control.Monad.Trans+import Control.Applicative+import Control.Monad.IO.Class+import Control.Monad.Resumption++-- | Reactive resumption monad transformer.+newtype ReacT input output m a = + ReacT { deReacT :: m (Either a (output, input -> ReacT input output m a)) }++instance Monad m => Monad (ReacT input output m) where+ return = ReacT . return . Left+ ReacT comp >>= f = ReacT $ do+ inner <- comp+ case inner of+ Left v -> deReacT (f v)+ Right (output, resume) -> return (Right (output,\ p -> resume p >>= f))++instance MonadTrans (ReacT input output) where+ lift m = ReacT $ m >>= return . Left++instance Monad m => Functor (ReacT input output m) where+ fmap f (ReacT m) = ReacT (m >>= \ r -> case r of+ Left v -> return (Left (f v))+ Right (o,k) -> return (Right (o,\ i -> fmap f (k i))))++instance Monad m => Applicative (ReacT input output m) where+ pure = return+ (<*>) = ap++instance MonadIO m => MonadIO (ReacT input output m) where+ liftIO = lift . liftIO++-- | Outputs its argument, then waits for the next input and returns it.+signal :: Monad m => output -> ReacT input output m input+signal o = ReacT (return (Right (o,return)))++-- | Tennis operator.+(<~>) :: Monad m => ReacT i o m a -> ReacT o i m b -> ResT m (Either a b)+m1 <~> m2 = do r1 <- lift (deReacT m1)+ case r1 of+ Left v -> return (Left v)+ Right (o1,k1) -> do+ r2 <- lift (deReacT m2)+ case r2 of+ Left v -> return (Right v)+ Right (o2,k2) -> k1 o2 <~> k2 o1
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2013, Ian Graves++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Ian Graves nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,4 @@+monad-resumption+=================++This library implements resumption and reactive resumption monads for use in resumption-passing style programming in Haskell. For more information on the basis behind Resumptions in Haskell, [Cheap (But Functional) Threads](http://people.cs.missouri.edu/~harrisonwl/drafts/CheapThreads.pdf) is an advisable read.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ monad-resumption.cabal view
@@ -0,0 +1,27 @@+-- Initial resumption_monads.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++name: monad-resumption+version: 0.1.0.1+synopsis: Resumption and reactive resumption monads for Haskell.+description: Resumption and reactive-resumption monads for Haskell.+homepage: https://github.com/igraves/resumption_monads+license: BSD3+license-file: LICENSE+author: Ian Graves, Adam Procter+maintainer: Ian Graves <thegravian@gmail.com>+-- copyright: +category: Control+build-type: Simple+extra-source-files: README.md+cabal-version: >=1.10++library+ exposed-modules: + Control.Monad.Resumption+ Control.Monad.Resumption.Reactive+ -- other-modules: + -- other-extensions: + build-depends: base >=4.6 && <4.7, transformers, mtl+ -- hs-source-dirs: + default-language: Haskell2010