module MonadUtils where

import Control.Monad (liftM2, liftM3)
import Control.Monad.State (MonadState (get, put))

liftM1' :: (Monad m) => (a' -> m a) -> (a -> b) -> a' -> m b
liftM1' :: forall (m :: * -> *) a' a b.
Monad m =>
(a' -> m a) -> (a -> b) -> a' -> m b
liftM1' a' -> m a
lifter a -> b
f a'
a = a -> b
f (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a' -> m a
lifter a'
a

liftM2' :: (Monad m) => (a' -> m a) -> (a -> a -> b) -> a' -> a' -> m b
liftM2' :: forall (m :: * -> *) a' a b.
Monad m =>
(a' -> m a) -> (a -> a -> b) -> a' -> a' -> m b
liftM2' a' -> m a
lifter a -> a -> b
f a'
a a'
b = (a -> a -> b) -> m a -> m a -> m b
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 a -> a -> b
f (a' -> m a
lifter a'
a) (a' -> m a
lifter a'
b)

liftM3' :: (Monad m) => (a' -> m a) -> (a -> a -> a -> b) -> a' -> a' -> a' -> m b
liftM3' :: forall (m :: * -> *) a' a b.
Monad m =>
(a' -> m a) -> (a -> a -> a -> b) -> a' -> a' -> a' -> m b
liftM3' a' -> m a
lifter a -> a -> a -> b
f a'
a a'
b a'
c = (a -> a -> a -> b) -> m a -> m a -> m a -> m b
forall (m :: * -> *) a1 a2 a3 r.
Monad m =>
(a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
liftM3 a -> a -> a -> b
f (a' -> m a
lifter a'
a) (a' -> m a
lifter a'
b) (a' -> m a
lifter a'
c)

locally :: (MonadState s m) => m a -> m a
locally :: forall s (m :: * -> *) a. MonadState s m => m a -> m a
locally m a
computation = do
  s
oldState <- m s
forall s (m :: * -> *). MonadState s m => m s
get
  a
result <- m a
computation
  s -> m ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put s
oldState
  a -> m a
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
result