{-# LANGUAGE UndecidableInstances #-}

module Blucontrol.Monad.PrepareValue.Modifier (
  PrepareValueModifierT
, runPrepareValueModifierT
) where

import Control.Monad.Base
import Control.Monad.Except
import Control.Monad.Reader
import Control.Monad.Trans.Control

import Blucontrol.Monad.PrepareValue

newtype PrepareValueModifierT m a = PrepareValueModifierT { PrepareValueModifierT m a
-> ReaderT (PreparedValue m -> IO (PreparedValue m)) m a
unPrepareValueModifierT :: ReaderT (PreparedValue m -> IO (PreparedValue m)) m a }
  deriving (Functor (PrepareValueModifierT m)
a -> PrepareValueModifierT m a
Functor (PrepareValueModifierT m)
-> (forall a. a -> PrepareValueModifierT m a)
-> (forall a b.
    PrepareValueModifierT m (a -> b)
    -> PrepareValueModifierT m a -> PrepareValueModifierT m b)
-> (forall a b c.
    (a -> b -> c)
    -> PrepareValueModifierT m a
    -> PrepareValueModifierT m b
    -> PrepareValueModifierT m c)
-> (forall a b.
    PrepareValueModifierT m a
    -> PrepareValueModifierT m b -> PrepareValueModifierT m b)
-> (forall a b.
    PrepareValueModifierT m a
    -> PrepareValueModifierT m b -> PrepareValueModifierT m a)
-> Applicative (PrepareValueModifierT m)
PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m b
PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m a
PrepareValueModifierT m (a -> b)
-> PrepareValueModifierT m a -> PrepareValueModifierT m b
(a -> b -> c)
-> PrepareValueModifierT m a
-> PrepareValueModifierT m b
-> PrepareValueModifierT m c
forall a. a -> PrepareValueModifierT m a
forall a b.
PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m a
forall a b.
PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m b
forall a b.
PrepareValueModifierT m (a -> b)
-> PrepareValueModifierT m a -> PrepareValueModifierT m b
forall a b c.
(a -> b -> c)
-> PrepareValueModifierT m a
-> PrepareValueModifierT m b
-> PrepareValueModifierT m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *).
Applicative m =>
Functor (PrepareValueModifierT m)
forall (m :: * -> *) a.
Applicative m =>
a -> PrepareValueModifierT m a
forall (m :: * -> *) a b.
Applicative m =>
PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m a
forall (m :: * -> *) a b.
Applicative m =>
PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m b
forall (m :: * -> *) a b.
Applicative m =>
PrepareValueModifierT m (a -> b)
-> PrepareValueModifierT m a -> PrepareValueModifierT m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> PrepareValueModifierT m a
-> PrepareValueModifierT m b
-> PrepareValueModifierT m c
<* :: PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m a
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m a
*> :: PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m b
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m b
liftA2 :: (a -> b -> c)
-> PrepareValueModifierT m a
-> PrepareValueModifierT m b
-> PrepareValueModifierT m c
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> PrepareValueModifierT m a
-> PrepareValueModifierT m b
-> PrepareValueModifierT m c
<*> :: PrepareValueModifierT m (a -> b)
-> PrepareValueModifierT m a -> PrepareValueModifierT m b
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
PrepareValueModifierT m (a -> b)
-> PrepareValueModifierT m a -> PrepareValueModifierT m b
pure :: a -> PrepareValueModifierT m a
$cpure :: forall (m :: * -> *) a.
Applicative m =>
a -> PrepareValueModifierT m a
$cp1Applicative :: forall (m :: * -> *).
Applicative m =>
Functor (PrepareValueModifierT m)
Applicative, a -> PrepareValueModifierT m b -> PrepareValueModifierT m a
(a -> b) -> PrepareValueModifierT m a -> PrepareValueModifierT m b
(forall a b.
 (a -> b) -> PrepareValueModifierT m a -> PrepareValueModifierT m b)
-> (forall a b.
    a -> PrepareValueModifierT m b -> PrepareValueModifierT m a)
-> Functor (PrepareValueModifierT m)
forall a b.
a -> PrepareValueModifierT m b -> PrepareValueModifierT m a
forall a b.
(a -> b) -> PrepareValueModifierT m a -> PrepareValueModifierT m b
forall (m :: * -> *) a b.
Functor m =>
a -> PrepareValueModifierT m b -> PrepareValueModifierT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> PrepareValueModifierT m a -> PrepareValueModifierT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> PrepareValueModifierT m b -> PrepareValueModifierT m a
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> PrepareValueModifierT m b -> PrepareValueModifierT m a
fmap :: (a -> b) -> PrepareValueModifierT m a -> PrepareValueModifierT m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> PrepareValueModifierT m a -> PrepareValueModifierT m b
Functor, Applicative (PrepareValueModifierT m)
a -> PrepareValueModifierT m a
Applicative (PrepareValueModifierT m)
-> (forall a b.
    PrepareValueModifierT m a
    -> (a -> PrepareValueModifierT m b) -> PrepareValueModifierT m b)
-> (forall a b.
    PrepareValueModifierT m a
    -> PrepareValueModifierT m b -> PrepareValueModifierT m b)
-> (forall a. a -> PrepareValueModifierT m a)
-> Monad (PrepareValueModifierT m)
PrepareValueModifierT m a
-> (a -> PrepareValueModifierT m b) -> PrepareValueModifierT m b
PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m b
forall a. a -> PrepareValueModifierT m a
forall a b.
PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m b
forall a b.
PrepareValueModifierT m a
-> (a -> PrepareValueModifierT m b) -> PrepareValueModifierT m b
forall (m :: * -> *).
Monad m =>
Applicative (PrepareValueModifierT m)
forall (m :: * -> *) a. Monad m => a -> PrepareValueModifierT m a
forall (m :: * -> *) a b.
Monad m =>
PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m b
forall (m :: * -> *) a b.
Monad m =>
PrepareValueModifierT m a
-> (a -> PrepareValueModifierT m b) -> PrepareValueModifierT m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> PrepareValueModifierT m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> PrepareValueModifierT m a
>> :: PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
PrepareValueModifierT m a
-> PrepareValueModifierT m b -> PrepareValueModifierT m b
>>= :: PrepareValueModifierT m a
-> (a -> PrepareValueModifierT m b) -> PrepareValueModifierT m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
PrepareValueModifierT m a
-> (a -> PrepareValueModifierT m b) -> PrepareValueModifierT m b
$cp1Monad :: forall (m :: * -> *).
Monad m =>
Applicative (PrepareValueModifierT m)
Monad, MonadBase b, MonadBaseControl b)
-- TODO: A `MonadTransControl` instance seems to be impossible

instance MonadTrans PrepareValueModifierT where
  lift :: m a -> PrepareValueModifierT m a
lift = ReaderT (PreparedValue m -> IO (PreparedValue m)) m a
-> PrepareValueModifierT m a
forall (m :: * -> *) a.
ReaderT (PreparedValue m -> IO (PreparedValue m)) m a
-> PrepareValueModifierT m a
PrepareValueModifierT (ReaderT (PreparedValue m -> IO (PreparedValue m)) m a
 -> PrepareValueModifierT m a)
-> (m a -> ReaderT (PreparedValue m -> IO (PreparedValue m)) m a)
-> m a
-> PrepareValueModifierT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> ReaderT (PreparedValue m -> IO (PreparedValue m)) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift

instance (MonadBase IO m, MonadPrepareValue m) => MonadPrepareValue (PrepareValueModifierT m) where
  type PreparedValue (PrepareValueModifierT m) = PreparedValue m
  preparedValue :: PrepareValueModifierT m (PreparedValue (PrepareValueModifierT m))
preparedValue = do
    PreparedValue m
oldValue <- m (PreparedValue m) -> PrepareValueModifierT m (PreparedValue m)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (PreparedValue m)
forall (m :: * -> *). MonadPrepareValue m => m (PreparedValue m)
preparedValue
    PreparedValue m -> IO (PreparedValue m)
modifyValue <- ReaderT
  (PreparedValue m -> IO (PreparedValue m))
  m
  (PreparedValue m -> IO (PreparedValue m))
-> PrepareValueModifierT
     m (PreparedValue m -> IO (PreparedValue m))
forall (m :: * -> *) a.
ReaderT (PreparedValue m -> IO (PreparedValue m)) m a
-> PrepareValueModifierT m a
PrepareValueModifierT ReaderT
  (PreparedValue m -> IO (PreparedValue m))
  m
  (PreparedValue m -> IO (PreparedValue m))
forall r (m :: * -> *). MonadReader r m => m r
ask
    IO (PreparedValue m) -> PrepareValueModifierT m (PreparedValue m)
forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
liftBase (IO (PreparedValue m) -> PrepareValueModifierT m (PreparedValue m))
-> IO (PreparedValue m)
-> PrepareValueModifierT m (PreparedValue m)
forall a b. (a -> b) -> a -> b
$ PreparedValue m -> IO (PreparedValue m)
modifyValue PreparedValue m
oldValue

runPrepareValueModifierT :: (PreparedValue m -> IO (PreparedValue m)) -> PrepareValueModifierT m a -> m a
runPrepareValueModifierT :: (PreparedValue m -> IO (PreparedValue m))
-> PrepareValueModifierT m a -> m a
runPrepareValueModifierT PreparedValue m -> IO (PreparedValue m)
modify PrepareValueModifierT m a
tma = ReaderT (PreparedValue m -> IO (PreparedValue m)) m a
-> (PreparedValue m -> IO (PreparedValue m)) -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (PrepareValueModifierT m a
-> ReaderT (PreparedValue m -> IO (PreparedValue m)) m a
forall (m :: * -> *) a.
PrepareValueModifierT m a
-> ReaderT (PreparedValue m -> IO (PreparedValue m)) m a
unPrepareValueModifierT PrepareValueModifierT m a
tma) PreparedValue m -> IO (PreparedValue m)
modify