{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds   #-}

module Control.Monad.Freer.Extras.State (
      use
    , assign
    , modifying ) where

import Control.Lens (ASetter, Getting, over, set, view)
import Control.Monad.Freer (Eff, Member)
import Control.Monad.Freer.State (State, get, gets, put)

use :: Member (State s) effs => Getting a s a -> Eff effs a
use :: Getting a s a -> Eff effs a
use Getting a s a
accessor = (s -> a) -> Eff effs a
forall s a (effs :: [* -> *]).
Member (State s) effs =>
(s -> a) -> Eff effs a
gets (Getting a s a -> s -> a
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting a s a
accessor)

assign :: Member (State s) effs => ASetter s s a b -> b -> Eff effs ()
assign :: ASetter s s a b -> b -> Eff effs ()
assign ASetter s s a b
accessor b
value = Eff effs s
forall s (effs :: [* -> *]). Member (State s) effs => Eff effs s
get Eff effs s -> (s -> Eff effs ()) -> Eff effs ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= s -> Eff effs ()
forall s (effs :: [* -> *]).
Member (State s) effs =>
s -> Eff effs ()
put (s -> Eff effs ()) -> (s -> s) -> s -> Eff effs ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASetter s s a b -> b -> s -> s
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter s s a b
accessor b
value

modifying :: Member (State s) effs => ASetter s s a b -> (a -> b) -> Eff effs ()
modifying :: ASetter s s a b -> (a -> b) -> Eff effs ()
modifying ASetter s s a b
accessor a -> b
f = Eff effs s
forall s (effs :: [* -> *]). Member (State s) effs => Eff effs s
get Eff effs s -> (s -> Eff effs ()) -> Eff effs ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= s -> Eff effs ()
forall s (effs :: [* -> *]).
Member (State s) effs =>
s -> Eff effs ()
put (s -> Eff effs ()) -> (s -> s) -> s -> Eff effs ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASetter s s a b -> (a -> b) -> s -> s
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter s s a b
accessor a -> b
f