ytl-0.1.0.0: src/Yesod/Trans/Class/Reader.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Yesod.Trans.Class.Reader
( ReaderSite (..)
, runReaderSite
, SiteReader (..)
) where
import Yesod.Site.Class
import Yesod.Trans.Class
import Data.Copointed
import Yesod.Core
( RenderRoute (..)
)
-- | The class of sites which can read some data
class SiteReader r site | site -> r where
{-# MINIMAL (ask | reader), local #-}
-- | Get the data value
ask :: (MonadSite m) => m site r
ask = reader id
-- | Extract a value from the data
reader :: (MonadSite m) => (r -> a) -> m site a
reader f = f <$> ask
-- | Run a computation with a transformed version of the current data
-- value
local :: (MonadSite m) => (r -> r) -> m site a -> m site a
instance {-# OVERLAPPABLE #-}
(SiteTrans t, SiteReader r site) => SiteReader r (t site) where
ask = lift ask
reader f = lift $ reader f
local f = mapSiteT (local f)
-- | A site transformation which extends a site with some additional data
-- which can be read
data ReaderSite r site = ReaderSite
{ readVal :: r
, unReaderSite :: site
}
-- | Compute the effect of 'ReaderSite' by passing in the data value to be
-- used when reading
runReaderSite
:: (MonadSite m)
=> r
-> m (ReaderSite r site) a
-> m site a
runReaderSite r
= withSiteT (ReaderSite r)
instance Copointed (ReaderSite r) where
copoint = unReaderSite
instance {-# OVERLAPPING #-} SiteReader r (ReaderSite r site) where
ask = do
ReaderSite r _ <- askSite
pure r
local f = withSiteT (\(ReaderSite r site) -> ReaderSite (f r) site)
instance RenderRoute site => RenderRoute (ReaderSite r site) where
newtype Route (ReaderSite r site) = ReaderRoute (Route site)
renderRoute (ReaderRoute route) = renderRoute route
deriving instance Eq (Route site) => Eq (Route (ReaderSite r site))
instance SiteTrans (ReaderSite r) where
lift = withSiteT unReaderSite
mapSiteT runner argM = do
ReaderSite r _ <- askSite
withSiteT unReaderSite $ runner $ withSiteT (ReaderSite r) argM