webapp-0.0.1: Web/App/Monad.hs
{-# LANGUAGE OverloadedStrings, GeneralizedNewtypeDeriving #-}
{-|
Module : Web.App.Monad
Copyright : (c) Nathaniel Symer, 2015
License : MIT
Maintainer : nate@symer.io
Stability : experimental
Portability : POSIX
Definition of 'WebAppM' monad & 'WebAppState' typeclass.
-}
module Web.App.Monad
(
-- * Monads
WebAppM(..),
-- * Typeclasses
WebAppState(..),
-- * Cache Operations
getCache,
-- * State Operations
getState,
putState,
modifyState
) where
import Web.App.FileCache (FileCache)
import Web.App.Monad.Internal (WebApp(..))
import Control.Monad.Reader
import Control.Concurrent.STM
-- |Defines a common interface for an app's state
class WebAppState s where
-- |Create an app state
initState :: IO s
-- |Destroy an app state
destroyState :: s -- ^ the state to destroy
-> IO ()
-- |Monad providing a 'FileCache' and an application state
newtype WebAppM s a = WebAppM { runWebAppM :: ReaderT (TVar (WebApp s)) IO a }
deriving (Functor,Applicative,Monad,MonadIO,MonadReader (TVar (WebApp s)))
liftWebAppM :: (MonadTrans t, WebAppState s) => WebAppM s a -> t (WebAppM s) a
liftWebAppM = lift
-- |Get the 'FileCache' embedded in a 'WebAppM' monad
getCache :: (MonadTrans t, WebAppState s) => t (WebAppM s) FileCache
getCache = liftWebAppM $ ask >>= liftIO . fmap webAppCache . readTVarIO
-- |Get the state embedded in a 'WebAppM' monad
getState :: (MonadTrans t, WebAppState s) => t (WebAppM s) s
getState = liftWebAppM $ ask >>= liftIO . fmap webAppState . readTVarIO
-- |Embed a new state in a 'WebAppM' monad
putState :: (MonadTrans t, WebAppState s) => s -- ^ state to embed
-> t (WebAppM s) ()
putState st = liftWebAppM $ do
tv <- ask
liftIO $ atomically $ do
(WebApp cache _) <- readTVar tv
writeTVar tv (WebApp cache st)
-- |Apply a function to the state embedded in a 'WebAppM' monad
modifyState :: (MonadTrans t, WebAppState s) => (s -> s) -- ^ function to apply to state
-> t (WebAppM s) ()
modifyState f = liftWebAppM $ do
tv <- ask
liftIO $ atomically $ do
(WebApp cache st) <- readTVar tv
writeTVar tv (WebApp cache (f st))