{-# LANGUAGE TypeSynonymInstances, GeneralizedNewtypeDeriving, OverloadedStrings #-} -- | This module offers a simple implementation of @Localized@ class via @StateT@ transformer. -- This implementation is usable if you have nothing against adding yet another transformer to -- your already complicated monadic stack. Otherwise, it may be simpler for you to add necessary -- fields to one of @StateT@s or @ReaderT@s in your stack. module Text.Localize.State (-- * Data types LocState (..), LocalizeT (..), -- * Functions runLocalizeT, setLanguage, withLanguage, setContext, withContext ) where import Control.Applicative import Control.Monad.State import Control.Monad.Trans import Text.Localize.Types -- | Localization state data LocState = LocState { lsTranslations :: Translations, lsLanguage :: LanguageId, lsContext :: Maybe Context } deriving (Show) -- | Localization monad transformer newtype LocalizeT m a = LocalizeT { unLocalizeT :: StateT LocState m a } deriving (Functor, Applicative, Monad, MonadIO, MonadState LocState) instance Monad m => Localized (LocalizeT m) where getTranslations = gets lsTranslations getLanguage = gets lsLanguage getContext = gets lsContext -- | Run a computation inside @LocalizeT@. runLocalizeT :: Monad m => LocalizeT m a -> LocState -> m a runLocalizeT actions st = evalStateT (unLocalizeT actions) st -- | Set current language setLanguage :: Monad m => LanguageId -> LocalizeT m () setLanguage lang = modify $ \st -> st {lsLanguage = lang} -- | Execute some actions with specified language. withLanguage :: Monad m => LanguageId -> LocalizeT m a -> LocalizeT m a withLanguage lang actions = do oldLang <- gets lsLanguage setLanguage lang result <- actions setLanguage oldLang return result -- | Set current context. setContext :: Monad m => Maybe Context -> LocalizeT m () setContext ctxt = modify $ \st -> st {lsContext = ctxt} -- | Execute some actions within specific context. withContext :: Monad m => Maybe Context -> LocalizeT m a -> LocalizeT m a withContext ctxt actions = do oldContext <- gets lsContext setContext ctxt result <- actions setContext oldContext return result