Skip to content

Commit

Permalink
Introduce MonadTell, MonadAsk, remove MonadRWS
Browse files Browse the repository at this point in the history
  • Loading branch information
garyb committed Oct 10, 2016
1 parent 6ebb56c commit 35bc4f2
Show file tree
Hide file tree
Showing 13 changed files with 106 additions and 93 deletions.
6 changes: 4 additions & 2 deletions src/Control/Monad/Cont/Trans.purs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Prelude

import Control.Monad.Cont.Class (class MonadCont, callCC)
import Control.Monad.Eff.Class (class MonadEff, liftEff)
import Control.Monad.Reader.Class (class MonadReader, ask, local)
import Control.Monad.Reader.Class (class MonadAsk, class MonadReader, ask, local)
import Control.Monad.State.Class (class MonadState, state)
import Control.Monad.Trans (class MonadTrans, lift)

Expand Down Expand Up @@ -58,8 +58,10 @@ instance monadTransContT :: MonadTrans (ContT r) where
instance monadEffContT :: MonadEff eff m => MonadEff eff (ContT r m) where
liftEff = lift <<< liftEff

instance monadReaderContT :: MonadReader r1 m => MonadReader r1 (ContT r m) where
instance monadAskContT :: MonadAsk r1 m => MonadAsk r1 (ContT r m) where
ask = lift ask

instance monadReaderContT :: MonadReader r1 m => MonadReader r1 (ContT r m) where
local f (ContT c) = ContT \k -> do
r <- ask
local f (c (local (const (r :: r1)) <<< k))
Expand Down
15 changes: 8 additions & 7 deletions src/Control/Monad/Except/Trans.purs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ import Control.Alternative (class Alternative)
import Control.Monad.Cont.Class (class MonadCont, callCC)
import Control.Monad.Eff.Class (class MonadEff, liftEff)
import Control.Monad.Error.Class (class MonadError, throwError, catchError)
import Control.Monad.Reader.Class (class MonadReader, local, ask)
import Control.Monad.Reader.Class (class MonadAsk, class MonadReader, ask, local)
import Control.Monad.Rec.Class (class MonadRec, tailRecM, Step(..))
import Control.Monad.RWS.Class (class MonadRWS)
import Control.Monad.State.Class (class MonadState, state)
import Control.Monad.Trans (class MonadTrans, lift)
import Control.Monad.Writer.Class (class MonadWriter, pass, listen, writer)
import Control.Monad.Writer.Class (class MonadWriter, class MonadTell, pass, listen, tell)
import Control.MonadPlus (class MonadPlus)
import Control.MonadZero (class MonadZero)
import Control.Plus (class Plus)
Expand Down Expand Up @@ -119,15 +118,19 @@ instance monadErrorExceptT :: Monad m => MonadError e (ExceptT e m) where
catchError (ExceptT m) k =
ExceptT (m >>= either (\a -> case k a of ExceptT b -> b) (pure <<< Right))

instance monadReaderExceptT :: MonadReader r m => MonadReader r (ExceptT e m) where
instance monadAskExceptT :: MonadAsk r m => MonadAsk r (ExceptT e m) where
ask = lift ask

instance monadReaderExceptT :: MonadReader r m => MonadReader r (ExceptT e m) where
local f = mapExceptT (local f)

instance monadStateExceptT :: MonadState s m => MonadState s (ExceptT e m) where
state f = lift (state f)

instance monadTellExceptT :: MonadTell w m => MonadTell w (ExceptT e m) where
tell = lift <<< tell

instance monadWriterExceptT :: MonadWriter w m => MonadWriter w (ExceptT e m) where
writer wd = lift (writer wd)
listen = mapExceptT \m -> do
Tuple a w <- listen m
pure $ (\r -> Tuple r w) <$> a
Expand All @@ -136,5 +139,3 @@ instance monadWriterExceptT :: MonadWriter w m => MonadWriter w (ExceptT e m) wh
pure case a of
Left e -> Tuple (Left e) id
Right (Tuple r f) -> Tuple (Right r) f

instance monadRWSExceptT :: MonadRWS r w s m => MonadRWS r w s (ExceptT e m)
15 changes: 8 additions & 7 deletions src/Control/Monad/Maybe/Trans.purs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ import Control.Alternative (class Alternative)
import Control.Monad.Cont.Class (class MonadCont, callCC)
import Control.Monad.Eff.Class (class MonadEff, liftEff)
import Control.Monad.Error.Class (class MonadError, catchError, throwError)
import Control.Monad.Reader.Class (class MonadReader, local, ask)
import Control.Monad.Reader.Class (class MonadAsk, class MonadReader, ask, local)
import Control.Monad.Rec.Class (class MonadRec, tailRecM, Step(..))
import Control.Monad.RWS.Class (class MonadRWS)
import Control.Monad.State.Class (class MonadState, state)
import Control.Monad.Trans (class MonadTrans, lift)
import Control.Monad.Writer.Class (class MonadWriter, pass, listen, writer)
import Control.Monad.Writer.Class (class MonadWriter, class MonadTell, pass, listen, tell)
import Control.MonadPlus (class MonadPlus)
import Control.MonadZero (class MonadZero)
import Control.Plus (class Plus)
Expand Down Expand Up @@ -102,15 +101,19 @@ instance monadErrorMaybeT :: MonadError e m => MonadError e (MaybeT m) where
catchError (MaybeT m) h =
MaybeT $ catchError m (\a -> case h a of MaybeT b -> b)

instance monadReaderMaybeT :: MonadReader r m => MonadReader r (MaybeT m) where
instance monadAskMaybeT :: MonadAsk r m => MonadAsk r (MaybeT m) where
ask = lift ask

instance monadReaderMaybeT :: MonadReader r m => MonadReader r (MaybeT m) where
local f = mapMaybeT (local f)

instance monadStateMaybeT :: MonadState s m => MonadState s (MaybeT m) where
state f = lift (state f)

instance monadTellMaybeT :: MonadTell w m => MonadTell w (MaybeT m) where
tell = lift <<< tell

instance monadWriterMaybeT :: MonadWriter w m => MonadWriter w (MaybeT m) where
writer wd = lift (writer wd)
listen = mapMaybeT \m -> do
Tuple a w <- listen m
pure $ (\r -> Tuple r w) <$> a
Expand All @@ -119,5 +122,3 @@ instance monadWriterMaybeT :: MonadWriter w m => MonadWriter w (MaybeT m) where
pure case a of
Nothing -> Tuple Nothing id
Just (Tuple v f) -> Tuple (Just v) f

instance monadRWSMaybeT :: MonadRWS r w s m => MonadRWS r w s (MaybeT m)
7 changes: 5 additions & 2 deletions src/Control/Monad/RWS.purs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@ module Control.Monad.RWS
, execRWS
, mapRWS
, withRWS
, module Control.Monad.RWS.Class
, module Control.Monad.RWS.Trans
, module Exports
) where

import Prelude

import Control.Monad.RWS.Class (class MonadRWS, class MonadReader, class MonadState, class MonadTrans, class MonadWriter, ask, censor, get, gets, lift, listen, listens, local, modify, pass, put, reader, state, tell, writer)
import Control.Monad.Reader.Class (ask, asks, local) as Exports
import Control.Monad.RWS.Trans (class MonadTrans, RWSResult(..), RWST(..), evalRWST, execRWST, lift, mapRWST, runRWST, withRWST)
import Control.Monad.State.Class (get, gets, state, put, modify) as Exports
import Control.Monad.Trans (lift) as Exports
import Control.Monad.Writer.Class (censor, listen, listens, pass, tell) as Exports

import Data.Identity (Identity(..))
import Data.Newtype (unwrap)
Expand Down
22 changes: 0 additions & 22 deletions src/Control/Monad/RWS/Class.purs

This file was deleted.

16 changes: 8 additions & 8 deletions src/Control/Monad/RWS/Trans.purs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@ module Control.Monad.RWS.Trans
( RWSResult(..)
, RWST(..), runRWST, evalRWST, execRWST, mapRWST, withRWST
, module Control.Monad.Trans
, module Control.Monad.RWS.Class
) where

import Prelude

import Control.Monad.Eff.Class (class MonadEff, liftEff)
import Control.Monad.Error.Class (class MonadError, throwError, catchError)
import Control.Monad.Reader.Class (class MonadReader)
import Control.Monad.Reader.Class (class MonadAsk, class MonadReader)
import Control.Monad.Rec.Class (class MonadRec, tailRecM, Step(..))
import Control.Monad.RWS.Class (class MonadRWS)
import Control.Monad.State.Class (class MonadState)
import Control.Monad.Trans (class MonadTrans, lift)
import Control.Monad.Writer.Class (class MonadWriter)
import Control.Monad.Writer.Class (class MonadWriter, class MonadTell)

import Data.Monoid (class Monoid, mempty)
import Data.Newtype (class Newtype)
Expand Down Expand Up @@ -78,15 +76,19 @@ instance monadTransRWST :: Monoid w => MonadTrans (RWST r w s) where
instance monadEffRWS :: (Monoid w, MonadEff eff m) => MonadEff eff (RWST r w s m) where
liftEff = lift <<< liftEff

instance monadReaderRWST :: (Monad m, Monoid w) => MonadReader r (RWST r w s m) where
instance monadAskRWST :: (Monad m, Monoid w) => MonadAsk r (RWST r w s m) where
ask = RWST \r s -> pure $ RWSResult s r mempty

instance monadReaderRWST :: (Monad m, Monoid w) => MonadReader r (RWST r w s m) where
local f m = RWST \r s -> case m of RWST m' -> m' (f r) s

instance monadStateRWST :: (Monad m, Monoid w) => MonadState s (RWST r w s m) where
state f = RWST \_ s -> case f s of Tuple a s' -> pure $ RWSResult s' a mempty

instance monadTellRWST :: (Monad m, Monoid w) => MonadTell w (RWST r w s m) where
tell w = RWST \_ s -> pure $ RWSResult s unit w

instance monadWriterRWST :: (Monad m, Monoid w) => MonadWriter w (RWST r w s m) where
writer (Tuple a w) = RWST \_ s -> pure $ RWSResult s a w
listen m = RWST \r s ->
case m of RWST m' ->
m' r s >>= \(RWSResult s' a w) ->
Expand All @@ -96,8 +98,6 @@ instance monadWriterRWST :: (Monad m, Monoid w) => MonadWriter w (RWST r w s m)
m' r s >>= \(RWSResult s' (Tuple a f) w) ->
pure $ RWSResult s' a (f w)

instance monadRWSRWST :: (Monad m, Monoid w) => MonadRWS r w s (RWST r w s m)

instance monadErrorRWST :: (MonadError e m, Monoid w) => MonadError e (RWST r w s m) where
throwError e = lift (throwError e)
catchError m h = RWST $ \r s ->
Expand Down
2 changes: 1 addition & 1 deletion src/Control/Monad/Reader.purs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module Control.Monad.Reader

import Prelude

import Control.Monad.Reader.Class (class MonadReader, ask, local, reader)
import Control.Monad.Reader.Class (class MonadAsk, ask, asks, class MonadReader, local)
import Control.Monad.Reader.Trans (class MonadTrans, ReaderT(..), lift, mapReaderT, runReaderT, withReaderT)

import Data.Identity (Identity(..))
Expand Down
40 changes: 25 additions & 15 deletions src/Control/Monad/Reader/Class.purs
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,39 @@ module Control.Monad.Reader.Class where

import Prelude

-- | The `MonadReader` type class represents those monads which support a global context via
-- | `ask` and `local`.
-- | The `MonadAsk` type class represents those monads which support a global
-- | context that can be provided via the `ask` function.
-- |
-- | - `ask` reads the current context.
-- | - `local f x` changes the value of the local context during the execution of the action `x`.
-- | An implementation is provided for `ReaderT`, and for other monad
-- | transformers defined in this library.
-- |
-- | An implementation is provided for `ReaderT`, and for other monad transformers
-- | defined in this library.
-- |
-- | Laws:
-- | Law:
-- |
-- | - `do { ask ; ask } = ask`
class Monad m <= MonadAsk r m | m -> r where
ask :: m r

instance monadAskFun :: MonadAsk r ((->) r) where
ask = id

-- | Projects a value from the global context in a `MonadAsk`.
asks :: forall r m a. MonadAsk r m => (r -> a) -> m a
asks f = f <$> ask

-- | An extension of the `MonadAsk` class that introduces a function `local f x`
-- | that allows the value of the local context to be modified for the duration
-- | of the execution of action `x`.
-- |
-- | An implementation is provided for `ReaderT`, and for other monad
-- | transformers defined in this library.
-- |
-- | Laws in addition to the `MonadAsk` law:
-- |
-- | - `local f ask = f <$> ask`
-- | - `local _ (pure a) = pure a`
-- | - `local f (do { a <- x ; y }) = do { a <- local f x ; local f y }`
class Monad m <= MonadReader r m | m -> r where
ask :: m r
class MonadAsk r m <= MonadReader r m | m -> r where
local :: forall a. (r -> r) -> m a -> m a

-- | Read a value which depends on the global context in any `MonadReader`.
reader :: forall r m a. MonadReader r m => (r -> a) -> m a
reader f = pure <<< f =<< ask

instance monadReaderFun :: MonadReader r ((->) r) where
ask = id
local = (>>>)
12 changes: 8 additions & 4 deletions src/Control/Monad/Reader/Trans.purs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import Control.Alternative (class Alternative)
import Control.Monad.Cont.Class (class MonadCont, callCC)
import Control.Monad.Eff.Class (class MonadEff, liftEff)
import Control.Monad.Error.Class (class MonadError, catchError, throwError)
import Control.Monad.Reader.Class (class MonadReader, ask, local, reader)
import Control.Monad.Reader.Class (class MonadAsk, class MonadReader, ask, asks, local)
import Control.Monad.Rec.Class (class MonadRec, tailRecM)
import Control.Monad.State.Class (class MonadState, state)
import Control.Monad.Trans (class MonadTrans, lift)
import Control.Monad.Writer.Class (class MonadWriter, pass, listen, writer)
import Control.Monad.Writer.Class (class MonadWriter, class MonadTell, pass, listen, tell)
import Control.MonadPlus (class MonadPlus)
import Control.MonadZero (class MonadZero)
import Control.Plus (class Plus, empty)
Expand Down Expand Up @@ -89,15 +89,19 @@ instance monadErrorReaderT :: MonadError e m => MonadError e (ReaderT r m) where
catchError (ReaderT m) h =
ReaderT \r -> catchError (m r) (\e -> case h e of ReaderT f -> f r)

instance monadReaderReaderT :: Monad m => MonadReader r (ReaderT r m) where
instance monadAskReaderT :: Monad m => MonadAsk r (ReaderT r m) where
ask = ReaderT pure

instance monadReaderReaderT :: Monad m => MonadReader r (ReaderT r m) where
local = withReaderT

instance monadStateReaderT :: MonadState s m => MonadState s (ReaderT r m) where
state = lift <<< state

instance monadTellReaderT :: MonadTell w m => MonadTell w (ReaderT r m) where
tell = lift <<< tell

instance monadWriterReaderT :: MonadWriter w m => MonadWriter w (ReaderT r m) where
writer = lift <<< writer
listen = mapReaderT listen
pass = mapReaderT pass

Expand Down
14 changes: 9 additions & 5 deletions src/Control/Monad/State/Trans.purs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import Control.Lazy (class Lazy)
import Control.Monad.Cont.Class (class MonadCont, callCC)
import Control.Monad.Eff.Class (class MonadEff, liftEff)
import Control.Monad.Error.Class (class MonadError, catchError, throwError)
import Control.Monad.Reader.Class (class MonadReader, local, ask)
import Control.Monad.Reader.Class (class MonadAsk, class MonadReader, ask, local)
import Control.Monad.Rec.Class (class MonadRec, tailRecM, Step(..))
import Control.Monad.State.Class (class MonadState, get, gets, modify, put, state)
import Control.Monad.Trans (class MonadTrans, lift)
import Control.Monad.Writer.Class (class MonadWriter, pass, listen, writer)
import Control.Monad.Writer.Class (class MonadWriter, class MonadTell, pass, listen, tell)
import Control.MonadPlus (class MonadPlus)
import Control.MonadZero (class MonadZero)
import Control.Plus (class Plus, empty)
Expand Down Expand Up @@ -113,15 +113,19 @@ instance monadErrorStateT :: MonadError e m => MonadError e (StateT s m) where
catchError (StateT m) h =
StateT \s -> catchError (m s) (\e -> case h e of StateT f -> f s)

instance monadReaderStateT :: MonadReader r m => MonadReader r (StateT s m) where
instance monadAskStateT :: MonadAsk r m => MonadAsk r (StateT s m) where
ask = lift ask
local f = mapStateT (local f)

instance monadReaderStateT :: MonadReader r m => MonadReader r (StateT s m) where
local = mapStateT <<< local

instance monadStateStateT :: Monad m => MonadState s (StateT s m) where
state f = StateT $ pure <<< f

instance monadTellStateT :: MonadTell w m => MonadTell w (StateT s m) where
tell = lift <<< tell

instance monadWriterStateT :: MonadWriter w m => MonadWriter w (StateT s m) where
writer wd = lift (writer wd)
listen m = StateT \s ->
case m of
StateT m' -> do
Expand Down
2 changes: 1 addition & 1 deletion src/Control/Monad/Writer.purs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module Control.Monad.Writer

import Prelude

import Control.Monad.Writer.Class (class MonadWriter, censor, listen, listens, pass, tell, writer)
import Control.Monad.Writer.Class (class MonadTell, tell, class MonadWriter, censor, listen, listens, pass)
import Control.Monad.Writer.Trans (class MonadTrans, WriterT(..), execWriterT, lift, mapWriterT, runWriterT)

import Data.Identity (Identity(..))
Expand Down
Loading

0 comments on commit 35bc4f2

Please sign in to comment.