|
| 1 | +{-# LANGUAGE StandaloneKindSignatures #-} |
| 2 | +{-# LANGUAGE FlexibleInstances #-} |
| 3 | +{-# LANGUAGE MultiParamTypeClasses #-} |
| 4 | +{-# LANGUAGE UndecidableInstances #-} |
| 5 | +{-# LANGUAGE GeneralizedNewtypeDeriving #-} |
| 6 | + |
| 7 | +{-# LANGUAGE StandaloneDeriving #-} |
| 8 | +{-# LANGUAGE DerivingVia #-} |
| 9 | +module Control.Monad.Bypass |
| 10 | + ( Bypass |
| 11 | + ) where |
| 12 | + |
| 13 | +import Control.Monad.Reader |
| 14 | +import Control.Monad.State |
| 15 | +import Control.Monad.Writer |
| 16 | +import Data.Kind (Type) |
| 17 | + |
| 18 | +type Bypass :: ((Type -> Type) -> Type -> Type) -> (Type -> Type) -> Type -> Type |
| 19 | +newtype Bypass t m a = Bypass (t m a) deriving (Functor, Applicative, Monad, MonadTrans) |
| 20 | + |
| 21 | +instance MonadReader r m => MonadReader r (Bypass (ReaderT r') m) where |
| 22 | + ask = lift ask |
| 23 | + local f (Bypass (ReaderT x)) = Bypass . ReaderT $ local f . x |
| 24 | + reader = lift . reader |
| 25 | + |
| 26 | +instance (MonadWriter w m, Monoid w') => MonadWriter w (Bypass (WriterT w') m) where |
| 27 | + writer = lift . writer |
| 28 | + tell = lift . tell |
| 29 | + listen (Bypass (WriterT x)) = Bypass $ WriterT $ (\((a, w'), w) -> ((a, w), w')) <$> listen x |
| 30 | + pass (Bypass (WriterT x)) = Bypass $ WriterT $ (\((a,f),w') -> pass $ return ((a,w'),f)) =<< x |
| 31 | + |
| 32 | +instance MonadState s m => MonadState s (Bypass (StateT s') m) where |
| 33 | + get = lift get |
| 34 | + put = lift . put |
| 35 | + state = lift . state |
| 36 | + |
| 37 | +newtype ExampleT m a = ExampleT (ReaderT Int m a) deriving (Functor, Applicative, Monad) |
| 38 | + |
| 39 | +deriving via Bypass (ReaderT Int) m instance MonadReader r m => MonadReader r (ExampleT m) |
| 40 | + |
0 commit comments