{-# LANGUAGE RecursiveDo #-}
{-# LANGUAGE UndecidableInstances #-}
module Control.Monad.Circular
( CircularT,
runCircularT,
withCircular,
)
where
import Control.Monad.Except
import Control.Monad.Reader
import Control.Monad.State.Strict
import Control.Monad.Writer.Strict
import Data.HashMap.Lazy (HashMap)
import Data.HashMap.Lazy qualified as Map
import Data.Hashable (Hashable)
import Prelude
newtype CircularT k v m a = CircularT (StateT (HashMap k v) m a)
deriving
( (forall a b. (a -> b) -> CircularT k v m a -> CircularT k v m b)
-> (forall a b. a -> CircularT k v m b -> CircularT k v m a)
-> Functor (CircularT k v m)
forall a b. a -> CircularT k v m b -> CircularT k v m a
forall a b. (a -> b) -> CircularT k v m a -> CircularT k v m b
forall k v (m :: * -> *) a b.
Functor m =>
a -> CircularT k v m b -> CircularT k v m a
forall k v (m :: * -> *) a b.
Functor m =>
(a -> b) -> CircularT k v m a -> CircularT k v m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall k v (m :: * -> *) a b.
Functor m =>
(a -> b) -> CircularT k v m a -> CircularT k v m b
fmap :: forall a b. (a -> b) -> CircularT k v m a -> CircularT k v m b
$c<$ :: forall k v (m :: * -> *) a b.
Functor m =>
a -> CircularT k v m b -> CircularT k v m a
<$ :: forall a b. a -> CircularT k v m b -> CircularT k v m a
Functor,
Functor (CircularT k v m)
Functor (CircularT k v m)
-> (forall a. a -> CircularT k v m a)
-> (forall a b.
CircularT k v m (a -> b) -> CircularT k v m a -> CircularT k v m b)
-> (forall a b c.
(a -> b -> c)
-> CircularT k v m a -> CircularT k v m b -> CircularT k v m c)
-> (forall a b.
CircularT k v m a -> CircularT k v m b -> CircularT k v m b)
-> (forall a b.
CircularT k v m a -> CircularT k v m b -> CircularT k v m a)
-> Applicative (CircularT k v m)
forall a. a -> CircularT k v m a
forall a b.
CircularT k v m a -> CircularT k v m b -> CircularT k v m a
forall a b.
CircularT k v m a -> CircularT k v m b -> CircularT k v m b
forall a b.
CircularT k v m (a -> b) -> CircularT k v m a -> CircularT k v m b
forall a b c.
(a -> b -> c)
-> CircularT k v m a -> CircularT k v m b -> CircularT k v m c
forall {k} {v} {m :: * -> *}. Monad m => Functor (CircularT k v m)
forall k v (m :: * -> *) a. Monad m => a -> CircularT k v m a
forall k v (m :: * -> *) a b.
Monad m =>
CircularT k v m a -> CircularT k v m b -> CircularT k v m a
forall k v (m :: * -> *) a b.
Monad m =>
CircularT k v m a -> CircularT k v m b -> CircularT k v m b
forall k v (m :: * -> *) a b.
Monad m =>
CircularT k v m (a -> b) -> CircularT k v m a -> CircularT k v m b
forall k v (m :: * -> *) a b c.
Monad m =>
(a -> b -> c)
-> CircularT k v m a -> CircularT k v m b -> CircularT k v 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
$cpure :: forall k v (m :: * -> *) a. Monad m => a -> CircularT k v m a
pure :: forall a. a -> CircularT k v m a
$c<*> :: forall k v (m :: * -> *) a b.
Monad m =>
CircularT k v m (a -> b) -> CircularT k v m a -> CircularT k v m b
<*> :: forall a b.
CircularT k v m (a -> b) -> CircularT k v m a -> CircularT k v m b
$cliftA2 :: forall k v (m :: * -> *) a b c.
Monad m =>
(a -> b -> c)
-> CircularT k v m a -> CircularT k v m b -> CircularT k v m c
liftA2 :: forall a b c.
(a -> b -> c)
-> CircularT k v m a -> CircularT k v m b -> CircularT k v m c
$c*> :: forall k v (m :: * -> *) a b.
Monad m =>
CircularT k v m a -> CircularT k v m b -> CircularT k v m b
*> :: forall a b.
CircularT k v m a -> CircularT k v m b -> CircularT k v m b
$c<* :: forall k v (m :: * -> *) a b.
Monad m =>
CircularT k v m a -> CircularT k v m b -> CircularT k v m a
<* :: forall a b.
CircularT k v m a -> CircularT k v m b -> CircularT k v m a
Applicative,
Applicative (CircularT k v m)
Applicative (CircularT k v m)
-> (forall a b.
CircularT k v m a -> (a -> CircularT k v m b) -> CircularT k v m b)
-> (forall a b.
CircularT k v m a -> CircularT k v m b -> CircularT k v m b)
-> (forall a. a -> CircularT k v m a)
-> Monad (CircularT k v m)
forall a. a -> CircularT k v m a
forall a b.
CircularT k v m a -> CircularT k v m b -> CircularT k v m b
forall a b.
CircularT k v m a -> (a -> CircularT k v m b) -> CircularT k v m b
forall k v (m :: * -> *). Monad m => Applicative (CircularT k v m)
forall k v (m :: * -> *) a. Monad m => a -> CircularT k v m a
forall k v (m :: * -> *) a b.
Monad m =>
CircularT k v m a -> CircularT k v m b -> CircularT k v m b
forall k v (m :: * -> *) a b.
Monad m =>
CircularT k v m a -> (a -> CircularT k v m b) -> CircularT k v 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
$c>>= :: forall k v (m :: * -> *) a b.
Monad m =>
CircularT k v m a -> (a -> CircularT k v m b) -> CircularT k v m b
>>= :: forall a b.
CircularT k v m a -> (a -> CircularT k v m b) -> CircularT k v m b
$c>> :: forall k v (m :: * -> *) a b.
Monad m =>
CircularT k v m a -> CircularT k v m b -> CircularT k v m b
>> :: forall a b.
CircularT k v m a -> CircularT k v m b -> CircularT k v m b
$creturn :: forall k v (m :: * -> *) a. Monad m => a -> CircularT k v m a
return :: forall a. a -> CircularT k v m a
Monad,
MonadError e,
MonadReader r,
MonadWriter w
)
instance MonadTrans (CircularT k v) where
lift :: forall (m :: * -> *) a. Monad m => m a -> CircularT k v m a
lift = StateT (HashMap k v) m a -> CircularT k v m a
forall k v (m :: * -> *) a.
StateT (HashMap k v) m a -> CircularT k v m a
CircularT (StateT (HashMap k v) m a -> CircularT k v m a)
-> (m a -> StateT (HashMap k v) m a) -> m a -> CircularT k v m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> StateT (HashMap k v) m a
forall (m :: * -> *) a. Monad m => m a -> StateT (HashMap k v) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift
instance (MonadState s m) => MonadState s (CircularT k v m) where
get :: CircularT k v m s
get = m s -> CircularT k v m s
forall (m :: * -> *) a. Monad m => m a -> CircularT k v m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m s
forall s (m :: * -> *). MonadState s m => m s
get
put :: s -> CircularT k v m ()
put s
x = m () -> CircularT k v m ()
forall (m :: * -> *) a. Monad m => m a -> CircularT k v m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> CircularT k v m ()) -> m () -> CircularT k v m ()
forall a b. (a -> b) -> a -> b
$ s -> m ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put s
x
runCircularT :: (Hashable k, MonadFix m) => CircularT k v m a -> m a
runCircularT :: forall k (m :: * -> *) v a.
(Hashable k, MonadFix m) =>
CircularT k v m a -> m a
runCircularT (CircularT StateT (HashMap k v) m a
m) = StateT (HashMap k v) m a -> HashMap k v -> m a
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT StateT (HashMap k v) m a
m HashMap k v
forall a. Monoid a => a
mempty
withCircular ::
(Hashable k, MonadFix m) =>
k ->
CircularT k v m v ->
CircularT k v m v
withCircular :: forall k (m :: * -> *) v.
(Hashable k, MonadFix m) =>
k -> CircularT k v m v -> CircularT k v m v
withCircular k
key (CircularT StateT (HashMap k v) m v
action) = StateT (HashMap k v) m v -> CircularT k v m v
forall k v (m :: * -> *) a.
StateT (HashMap k v) m a -> CircularT k v m a
CircularT do
HashMap k v
cache <- StateT (HashMap k v) m (HashMap k v)
forall s (m :: * -> *). MonadState s m => m s
get
case k -> HashMap k v -> Maybe v
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
Map.lookup k
key HashMap k v
cache of
Just v
value -> v -> StateT (HashMap k v) m v
forall a. a -> StateT (HashMap k v) m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure v
value
Maybe v
Nothing -> mdo
(HashMap k v -> HashMap k v) -> StateT (HashMap k v) m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((HashMap k v -> HashMap k v) -> StateT (HashMap k v) m ())
-> (HashMap k v -> HashMap k v) -> StateT (HashMap k v) m ()
forall a b. (a -> b) -> a -> b
$ k -> v -> HashMap k v -> HashMap k v
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
Map.insert k
key v
actualValue
v
actualValue <- StateT (HashMap k v) m v
action
v -> StateT (HashMap k v) m v
forall a. a -> StateT (HashMap k v) m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure v
actualValue
{-# ANN withCircular ("HLint: ignore Use onNothing" :: String) #-}