The context isn't a property of the monad abstraction, but
of a concrete monad, like the State monad.
If you desugar everything from the State monad, than you
can see, that the state 'c' is an explicit argument, which
is hidden in the "sugared" version.
import Control.Monad.State.Lazy
type Counter = State Int
-- using the State monad and the do notation
increment :: Counter ()
increment = do
c <- get
put $ c + 1
-- using the State monad and desugar the do notation
increment_ :: Counter ()
increment_ = get >>= \c -> put $ c + 1
-- desugar 'get'
get_ = \c -> (c, c)
-- desugar 'put'
put_ c = \_ -> ((), c)
-- desugar >>=
bind_ a b = \c -> let (result, c') = a c in (b result) c'
-- "desugar" the State monad
increment__ = get_ `bind_` \c -> put_ $ c + 1
Comments
The context isn't a property of the monad abstraction, but of a concrete monad, like the State monad.
If you desugar everything from the State monad, than you can see, that the state 'c' is an explicit argument, which is hidden in the "sugared" version.