Skip to content

Instantly share code, notes, and snippets.

@cgibbard
Created September 2, 2019 05:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cgibbard/1c6c50b76a1865ec151ec0b7f71c8cf5 to your computer and use it in GitHub Desktop.
Save cgibbard/1c6c50b76a1865ec151ec0b7f71c8cf5 to your computer and use it in GitHub Desktop.
How MonadState could potentially look, using DefaultSignatures and type equality constraints.
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
import Control.Monad.Trans.Class
import qualified Control.Monad.Trans.State as State
import Control.Monad.Trans.Identity (IdentityT)
import Control.Monad.Trans.Reader (ReaderT)
import Control.Monad.Trans.Writer (WriterT)
import Control.Monad.Trans.State (StateT)
import Control.Monad.Trans.Maybe (MaybeT)
import Control.Monad.Trans.Except (ExceptT)
import Control.Monad.Trans.Cont (ContT)
class Monad m => MonadState s m | m -> s where
get :: m s
put :: s -> m ()
-- These implementations work when the monad is some transformer applied to a monad
-- which is already an instance of MonadState s.
default get :: (MonadTrans t, m ~ t n, MonadState s n) => m s
get = lift get
default put :: (MonadTrans t, m ~ t n, MonadState s n) => s -> m ()
put s = lift (put s)
-- This instance uses actual implementations of the operations
instance Monad m => MonadState s (StateT s m) where
get = State.get
put = State.put
-- These instances use the default lifting instance behaviour from the class declaration, so
-- they can simply be blank. We only have to point out that we want them at all.
instance MonadState s m => MonadState s (IdentityT m)
instance MonadState s m => MonadState s (ReaderT e m)
instance (MonadState s m, Monoid w) => MonadState s (WriterT w m)
instance MonadState s m => MonadState s (MaybeT m)
instance MonadState s m => MonadState s (ExceptT e m)
instance MonadState s m => MonadState s (ContT r m)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment