functor-monad-0.1.1.0: src/FMonad/State/Day.hs
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DeriveFunctor #-}
module FMonad.State.Day
(StateT(..),
flift,
toOuter, fromOuter, toInner, fromInner,
State, state, state_, get, put,
runState
) where
import Control.Monad.Trans.Identity
import Data.Functor.Day ( Day(..), day )
import Data.Functor.Day.Curried ( Curried(Curried) )
import Data.Functor.Day.Comonoid
import FMonad
import FMonad.Adjoint
import FStrong
import qualified FMonad.State.Simple.Inner as Simple.Inner
import qualified FMonad.State.Simple.Outer as Simple.Outer
import Data.Functor.Day.Extra
import Data.Coerce (coerce)
import Data.Functor.Identity
import Data.Function ((&))
newtype StateT s mm x a = StateT { runStateT :: forall r. s (a -> r) -> mm (Day s x) r }
deriving stock Functor
deriving (FFunctor, FMonad) via (AdjointT (Day s) (Curried s) mm)
toAdjointT :: StateT s mm x ~> AdjointT (Day s) (Curried s) mm x
toAdjointT = coerce
fromAdjointT :: AdjointT (Day s) (Curried s) mm x ~> StateT s mm x
fromAdjointT = coerce
flift :: (Functor s, FStrong mm, Functor x)
=> mm x ~> StateT s mm x
flift mm = StateT $ \sf -> fstrength' (day sf mm)
toOuter :: (Functor x, FFunctor mm) => StateT ((,) s0) mm x ~> Simple.Outer.StateT s0 mm x
toOuter = Simple.Outer.fromAdjointT . AdjointT . ffmap (ffmap dayToEnv) . curriedToReader . runAdjointT . toAdjointT
fromOuter :: (Functor x, FFunctor mm) => Simple.Outer.StateT s0 mm x ~> StateT ((,) s0) mm x
fromOuter = fromAdjointT . AdjointT . ffmap (ffmap envToDay) . readerToCurried . runAdjointT . Simple.Outer.toAdjointT
toInner :: (Functor x, FFunctor mm) => StateT ((->) s1) mm x ~> Simple.Inner.StateT s1 mm x
toInner = Simple.Inner.fromAdjointT . AdjointT . ffmap (ffmap dayToTraced) . curriedToWriter . runAdjointT . toAdjointT
fromInner :: (Functor x, FFunctor mm) => Simple.Inner.StateT s1 mm x ~> StateT ((->) s1) mm x
fromInner = fromAdjointT . AdjointT . ffmap (ffmap tracedToDay) . writerToCurried . runAdjointT . Simple.Inner.toAdjointT
type State s = StateT s IdentityT
state :: (FMonad mm)
=> (forall r. s (a -> r) -> Day s x r)
-> StateT s mm x a
state f = StateT $ \sar -> fpure (f sar)
state_ :: (Functor s, FMonad mm)
=> (forall b. s b -> (s b, x a))
-> StateT s mm x a
state_ f = state (uncurry day . f)
get :: (Comonoid s, FMonad mm) => StateT s mm s ()
get = state (fmap ($ ()) . coapply)
put :: (Comonad s, FMonad mm) => s a -> StateT s mm Identity a
put sa = state (\sar -> Day sa (Identity (extract sar)) (&))
runState :: State s x a -> s (a -> r) -> Day s x r
runState sx = runIdentityT . runStateT sx