monadLib 3.6.2 → 3.7.1
raw patch · 4 files changed
+90/−30 lines, 4 files
Files
- monadLib.cabal +1/−1
- src/MonadLib.hs +47/−18
- src/MonadLib/Derive.hs +41/−9
- src/MonadLib/Monads.hs +1/−2
monadLib.cabal view
@@ -1,5 +1,5 @@ Name: monadLib-Version: 3.6.2+Version: 3.7.1 License: BSD3 License-file: LICENSE Author: Iavor S. Diatchki
src/MonadLib.hs view
@@ -1,5 +1,7 @@ {-# LANGUAGE CPP, MultiParamTypeClasses, FunctionalDependencies, UndecidableInstances, FlexibleInstances #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ScopedTypeVariables #-} {-| This library provides a collection of monad transformers that can be combined to produce various monads. -}@@ -20,7 +22,7 @@ -- * Effect Classes -- $Effects ReaderM(..), WriterM(..), StateM(..), ExceptionM(..), ContM(..), AbortM(..),- Label, labelCC, jump,+ Label, labelCC, labelCC_, jump, labelC, callCC, -- * Execution @@ -570,29 +572,39 @@ -- | Classifies monads that provide access to a computation's continuation. class Monad m => ContM m where -- | Capture the current continuation.- callCC :: ((a -> m b) -> m a) -> m a+ callWithCC :: ((a -> Label m) -> m a) -> m a ++-- This captures a common pattern in the lifted definitions of `callWithCC`.+liftJump :: (ContM m, MonadT t) =>+ (a -> b) ->+ ((a -> Label (t m)) -> t m a) ->+ ((b -> Label m ) -> t m a)+liftJump ans f l = f $ \a -> Lab (lift $ jump $ l $ ans a)++ instance (ContM m) => ContM (IdT m) where- callCC f = IT $ callCC $ \k -> runIdT $ f $ \a -> lift $ k a+ callWithCC f = IT $ callWithCC $ \k -> runIdT $ liftJump id f k instance (ContM m) => ContM (ReaderT i m) where- callCC f = R $ \r -> callCC $ \k -> runReaderT r $ f $ \a -> lift $ k a+ callWithCC f = R $ \r -> callWithCC $ \k -> runReaderT r $ liftJump id f k instance (ContM m) => ContM (StateT i m) where- callCC f = S $ \s -> callCC $ \k -> runStateT s $ f $ \a -> lift $ k (a,s)+ callWithCC f = S $ \s -> callWithCC $ \k -> runStateT s $ liftJump (ans s) f k+ where ans s a = (a,s) instance (ContM m,Monoid i) => ContM (WriterT i m) where- callCC f = W $ callCC $ \k -> unW $ f $ \a -> lift $ k (P a mempty)+ callWithCC f = W $ callWithCC $ \k -> unW $ liftJump (`P` mempty) f k instance (ContM m) => ContM (ExceptionT i m) where- callCC f = X $ callCC $ \k -> runExceptionT $ f $ \a -> lift $ k $ Right a+ callWithCC f = X $ callWithCC $ \k -> runExceptionT $ liftJump Right f k instance (ContM m) => ContM (ChoiceT m) where- callCC f = ChoiceEff $ callCC $ \k -> return $ f $ \a -> lift $ k $ Answer a+ callWithCC f = ChoiceEff $ callWithCC $ \k -> return $ liftJump Answer f k -- ??? What does this do ??? instance (Monad m) => ContM (ContT i m) where- callCC f = C $ \k -> runContT k $ f $ \a -> C $ \_ -> k a+ callWithCC f = C $ \k -> runContT k $ f $ \a -> Lab (C $ \_ -> k a) -- $Nested_Exec --@@ -718,21 +730,38 @@ -------------------------------------------------------------------------------- -- Some convenient functions for working with continuations. --- | An explicit representation for continuations that store a value.-newtype Label m a = Lab (a -> m ())+-- | An explicit representation for monadic continuarions.+newtype Label m = Lab (forall b. m b) -- | Capture the current continuation. -- This function is like 'return', except that it also captures -- the current continuation. Later, we can use 'jump' to repeat the -- computation from this point onwards but with a possibly different value.-labelCC :: (ContM m) => a -> m (a, Label m a)-labelCC x = callCC (\k -> let label = Lab (\a -> k (a, label))- in return (x, label))+labelCC :: (ContM m) => a -> m (a, a -> Label m)+labelCC x = callWithCC (\l -> let label a = Lab (jump (l (a, label)))+ in return (x, label)) --- | Change the value passed to a previously captured continuation.-jump :: (ContM m) => a -> Label m a -> m b-jump x (Lab k) = k x >> return unreachable- where unreachable = error "(bug) jump: unreachable"+-- | Capture the current continuation.+-- Later we can use `jump` to restart the program from this point.+labelCC_ :: forall m. (ContM m) => m (Label m)+labelCC_ = callWithCC $ \k -> let x :: m a -- Signature matters!!!+ x = jump (k (Lab x))+ in x++-- | A version of `callWithCC` that avoids the need for an explicit+-- use of the `jump` function.+callCC :: ContM m => ((a -> m b) -> m a) -> m a+callCC f = callWithCC $ \l -> f $ \a -> jump $ l a++-- | Label a given continuation.+labelC :: (forall b. m b) -> Label m+labelC k = Lab k++-- | Restart a previously captured computation.+jump :: Label m -> m a+jump (Lab k) = k++ --------------------------------------------------------------------------------
src/MonadLib/Derive.hs view
@@ -1,19 +1,34 @@+{-# LANGUAGE Rank2Types #-}+ {-| This module defines a number of functions that make it easy to get the functionality of MonadLib for user-defined newtypes. -} module MonadLib.Derive (- Iso(Iso), derive_fmap, derive_return, derive_bind, derive_fail, derive_mfix,- derive_ask, derive_put, derive_get, derive_set, derive_raise, derive_callCC,- derive_abort,- derive_local, derive_collect, derive_try,+ Iso(Iso),+ derive_fmap,+ derive_pure, derive_apply,+ derive_empty, derive_or,+ derive_return, derive_bind, derive_fail, derive_mzero, derive_mplus,- derive_lift, derive_inBase,+ derive_mfix,+ derive_ask,+ derive_local,+ derive_put,+ derive_collect,+ derive_get,+ derive_set,+ derive_raise,+ derive_try,+ derive_callWithCC,+ derive_abort,+ derive_lift,+ derive_inBase, derive_runM, ) where import MonadLib-import Control.Monad+import Control.Applicative import Control.Monad.Fix import Prelude hiding (Ordering(..)) @@ -26,6 +41,22 @@ derive_fmap :: (Functor m) => Iso m n -> (a -> b) -> n a -> n b derive_fmap iso f m = close iso (fmap f (open iso m)) +-- | Derive the implementation of 'pure' from 'Applicative'.+derive_pure :: (Applicative m) => Iso m n -> a -> n a+derive_pure iso a = close iso (pure a)++-- | Derive the implementation of '<*>' from 'Applicative'.+derive_apply :: (Applicative m) => Iso m n -> n (a -> b) -> (n a -> n b)+derive_apply iso f x = close iso (open iso f <*> open iso x)++-- | Derive the implementation of 'empty' from 'Alternative'.+derive_empty :: (Alternative m) => Iso m n -> n a+derive_empty iso = close iso empty++-- | Derive the implementation of '<|>' from 'Alternative'.+derive_or :: (Alternative m) => Iso m n -> n a -> n a -> n a+derive_or iso a b = close iso (open iso a <|> open iso b)+ -- | Derive the implementation of 'return' from 'Monad'. derive_return :: (Monad m) => Iso m n -> (a -> n a) derive_return iso a = close iso (return a)@@ -61,9 +92,10 @@ derive_raise :: (ExceptionM m i) => Iso m n -> i -> n a derive_raise iso x = close iso (raise x) --- | Derive the implementation of 'callCC' from 'ContM'.-derive_callCC :: (ContM m) => Iso m n -> ((a -> n b) -> n a) -> n a-derive_callCC iso f = close iso (callCC (open iso . f . (close iso .)))+-- | Derive the implementation of 'callWithCC' from 'ContM'.+derive_callWithCC :: (ContM m) => Iso m n -> ((a -> Label n) -> n a) -> n a+derive_callWithCC iso f = close iso $ callWithCC $ open iso . f . relab+ where relab k a = labelC (close iso $ jump $ k a) derive_abort :: (AbortM m i) => Iso m n -> i -> n a derive_abort iso i = close iso (abort i)
src/MonadLib/Monads.hs view
@@ -12,7 +12,6 @@ ) where import MonadLib import MonadLib.Derive-import Control.Monad import Control.Monad.Fix import Data.Monoid @@ -80,7 +79,7 @@ instance (Monoid i) => WriterM (Writer i) i where put = derive_put iso_W instance StateM (State i) i where get = derive_get iso_S; set = derive_set iso_S instance ExceptionM (Exception i) i where raise = derive_raise iso_X-instance ContM (Cont i) where callCC = derive_callCC iso_C+instance ContM (Cont i) where callWithCC = derive_callWithCC iso_C runReader :: i -> Reader i a -> a runWriter :: Writer i a -> (a,i)