zwirn-core-0.1.1.0: src/Zwirn/Core/State.hs
module Zwirn.Core.State where
{-
State.hs - functions manipulating the underlying state of signals
Copyright (C) 2025, Martin Gius
This library is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
-}
import Control.Monad.Identity
import qualified Data.Map as Map
import Zwirn.Core.Cord
import Zwirn.Core.Core
import Zwirn.Core.Types
--- functions modifying the state
modify' :: (st -> st) -> ZwirnT k st i a -> ZwirnT k st i a
modify' f x = zwirn $ \t st -> unzwirn x t (f st)
modify :: (MultiMonad k) => (ZwirnT k st i st -> ZwirnT k st i st) -> ZwirnT k st i a -> ZwirnT k st i a
modify f x = set (f (get x)) x
get :: (Applicative k) => ZwirnT k st i a -> ZwirnT k st i st
get = withValueState (\(v, st) -> (fmap (const st) v, st))
set :: (Monad k) => ZwirnT k st i st -> ZwirnT k st i a -> ZwirnT k st i a
set st a = withState . const <$> st <$$> a
-- functions to act on state that is a map
-- | get value of specific key, providing a function in case key is not found
getMap :: (MultiMonad k, Ord key) => (Maybe b -> ZwirnT k (Map.Map key b) i b) -> ZwirnT k (Map.Map key b) i key -> ZwirnT k (Map.Map key b) i b
getMap fromLookup xc = innerJoin $ liftA2 (\k l -> fromLookup $ Map.lookup k l) xc (get (pure ()))
-- | set value of given key
setMap :: (Monad k, Ord key) => ZwirnT k (Map.Map key b) i key -> ZwirnT k (Map.Map key b) i b -> ZwirnT k (Map.Map key b) i a -> ZwirnT k (Map.Map key b) i a
setMap key b = set (liftA2 Map.insert key b <*> get (pure ()))
-- | modify
modifyMap :: (MultiMonad k, Ord key) => (Maybe b -> ZwirnT k (Map.Map key b) i b) -> ZwirnT k (Map.Map key b) i key -> (ZwirnT k (Map.Map key b) i b -> ZwirnT k (Map.Map key b) i b) -> ZwirnT k (Map.Map key b) i a -> ZwirnT k (Map.Map key b) i a
modifyMap fromLookup key f = setMap key (f (getMap fromLookup key))