Если вы не боитесь использовать расширения, специфичные для GHC, вот простой подход к монадным трансформаторам:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Control.Monad.Reader
data ReaderData = ...
newtype MyMonad a = MyMonad (ReaderT ReaderData Snap a)
deriving (Monad, MonadReader ReaderData)
runMyMonad :: MyMonad a -> ReaderData -> Snap a
runMyMonad (MyMonad m) r = runReaderT m r
liftSnap :: Snap a -> MyMonad a
liftSnap act = MyMonad (lift act)
Теперь вы можете использовать ask
и local
для доступа к данным считывателя. Чтобы запустить действие в монаде Snap
, вам нужно «поднять» его в вашу новую монаду.
... r <- liftSnap $ ... snap action ...
Вы можете предпочесть более короткое имя. Так что, может быть, просто snap
.