urlpath-1.0.0: src/Data/Url.hs
{-# LANGUAGE
OverloadedStrings
, MultiParamTypeClasses
, FlexibleInstances
, FlexibleContexts
, KindSignatures
, InstanceSigs
, TypeFamilies
, RankNTypes
#-}
module Data.Url
( UrlReader (..)
, Url (..)
, module Data.Url.Types ) where
import Data.Url.Types
import Data.String
import Data.Monoid
import Data.Monoid.Textual (TextualMonoid)
import Control.Applicative
import Control.Monad
import Control.Monad.Trans
import Control.Monad.Reader.Class
-- * Classes
-- | @Url@ is a relationship between an underlying (monomorphic) string type
-- @plain@, and a deployment context @m@. We try to make the deployment style
-- coercible at the top level - if the expression has a type
-- @Url String (AbsoluteUrlT String Identity)@ or
-- @Monad m => Url T.Text (GroundedUrlT LT.Text m)@ will force
-- /all use-cases within the expression/ to coerce to that type.
class ( TextualMonoid plain
, MonadReader plain m
) => Url plain (m :: * -> *) where
url :: UrlString plain -- ^ Url type, parameterized over a string type @plain@
-> m plain -- ^ Rendered Url in some context.
plainUrl :: plain -- ^ raw small string
-> m plain -- ^ Rendered string in some context.
-- | Overload deployment schemes with this - then, all that's needed is a type
-- coercion to change deployment.
class Url plain m => UrlReader plain m where
type Result m :: * -> *
runUrlReader :: Url plain m =>
m b -- ^ MonadReader with index @string@ and result @b@
-> plain -- ^ Reader index
-> Result m b -- ^ Final result
instance ( Monad m
, TextualMonoid plain ) => Url plain (RelativeUrlT plain m) where
url = RelativeUrlT . const . return . expandRelative
plainUrl x = RelativeUrlT $ const $ return $ expandRelative $ UrlString x []
instance ( Monad m
, TextualMonoid plain ) => UrlReader plain (RelativeUrlT plain m) where
type Result (RelativeUrlT plain m) = m
runUrlReader = runRelativeUrlT
instance ( Monad m
, TextualMonoid plain ) => Url plain (GroundedUrlT plain m) where
url = GroundedUrlT . const . return . expandGrounded
plainUrl x = GroundedUrlT $ const $ return $ expandGrounded $ UrlString x []
instance ( Monad m
, TextualMonoid plain ) => UrlReader plain (GroundedUrlT plain m) where
type Result (GroundedUrlT plain m) = m
runUrlReader = runGroundedUrlT
instance ( Monad m
, TextualMonoid plain ) => Url plain (AbsoluteUrlT plain m) where
url = expandAbsolute
plainUrl x = expandAbsolute $ UrlString x []
instance ( Monad m
, TextualMonoid plain ) => UrlReader plain (AbsoluteUrlT plain m) where
type Result (AbsoluteUrlT plain m) = m
runUrlReader = runAbsoluteUrlT