{- here i show how to use lenses to handle states (didnt found any example on states in internet) -} {-# LANGUAGE TemplateHaskell #-} import Lens.Micro.TH (makeLenses) import Lens.Micro ((%~), (.~), (&), _2) import Lens.Micro.Platform (at) -- Correct import for Map operations import Data.IORef (IORef, newIORef, modifyIORef', readIORef) import Data.Map (Map) import qualified Data.Map as Map data AppState = AppState { _ui :: UIState , _user :: User } deriving (Show) data UIState = UIState { _theme :: String , _windowSize :: (Int, Int) , _keyBindings :: Map String String } deriving (Show) data User = User { _name :: String , _prefs :: UserPrefs } deriving (Show) data UserPrefs = UserPrefs { _fontSize :: Int , _darkMode :: Bool } deriving (Show) makeLenses ''AppState makeLenses ''UIState makeLenses ''User makeLenses ''UserPrefs main :: IO () main = do let initialState = AppState { _ui = UIState { _theme = "light" , _windowSize = (800, 600) , _keyBindings = Map.fromList [("Ctrl+S", "save")] } , _user = User { _name = "Alice" , _prefs = UserPrefs { _fontSize = 12 , _darkMode = False } } } stateRef <- newIORef initialState -- Corrected lens chain with & {- & is just backwards function application; x f , in which f will be applied to the value x -} modifyIORef' stateRef $ \s -> s & ui . keyBindings . at "Ctrl+X" .~ Just "cut" & user . prefs . darkMode .~ True & ui . windowSize . _2 %~ (+100) finalState <- readIORef stateRef print finalState