-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Painfully simple URL writing combinators -- -- Simple URL DSL for Haskell. -- -- This library tries to make it easier for people to write Url strings, -- structurally. Packages like Yesod Routes do a wonderful job at -- implementing string-free routing and references, but sometimes we have -- to compromise. This tries to make that compromise less painful. -- -- Use bare combinators to render your strings (kinda useless): -- --
-- expandRelative $ "foo.php" <?> ("key1","bar") <&> ("key2","baz")
--
-- ↪ "foo.php?key1=bar&key2=baz"
--
--
-- ... or use the MonadReader instance for a configurable host:
--
--
-- let path = runAbsoluteUrl $ url $ "foo.php" <?> ("key1","bar") <&> ("key2","baz")
-- path "example.com"
--
-- ↪ "example.com/foo.php?key1=bar&key2=baz"
--
--
-- url puts the UrlString in a MonadReader that we can
-- use for applying our host. We use different monads for different
-- deployment schemes (currently we have 3 - RelativeUrl,
-- GroundedUrl, and AbsoluteUrl), which we can
-- integrate in different libraries, like Lucid:
--
--
-- (runAbsoluteUrl $ renderTextT $ do
-- foo <- lift $ url $ "foo" <?> ("bar","baz")
-- script_ [src_ foo] "" )
-- ) "example.com"
--
-- ↪ "<script src=\"example.com/foo?bar=baz\"></script>"
--
--
-- ... and in Scotty ...
--
--
-- main :: IO ()
-- main = scottyT 3000
-- rootConf
-- rootConf
-- run
--
-- where
-- rootConf = flip runAbsoluteT "http://example.com"
--
-- run :: ( MonadIO m
-- , MonadReader T.Text m
-- , Url T.Text m ) =>
-- ScottyT LT.Text m ()
-- run = get "/" $ do
-- path <- lift $ url $ "foo" <?> ("bar","baz")
-- text $ LT.fromStrict path
--
-- λ> curl localhost:3000/
-- ↪ "http://example.com/foo?bar=baz"
--
--
-- Note that in the scotty example, we don't use one of our deployment
-- schemes - this is because the scottyT function expects it's
-- underlying monad to be an instance of MonadIO, which we can
-- only instantiate in our monad transformers.
--
-- Please take mind - the string type underlying the Url rendering is
-- generalized to Data.String.IsString for convenient use with
-- -XOverloadedStrings. However, due to that generality, we need
-- to specify the monomorphic type (like Data.Text.Text above).
@package urlpath
@version 0.2
module UrlPath.Types
-- | Abstract data type for a Url - a "target" and GET parameters. We
-- require IsString and Monoid for generic
-- construction, but rendering will require a monomorphic type.
--
-- The type constructor is parameterized over it's underlying
-- IsString & Monoid instance.
data UrlString a
UrlString :: a -> [(a, a)] -> UrlString a
-- | We can't provide a Show instance for UrlString
-- because that would force us to use String.
showUrlString :: UrlString a -> a
-- | Makes a UrlString out of a raw target path and a GET
-- parameter pair.
(>) :: (IsString a, Monoid a) => a -> (a, a) -> UrlString a
-- | Adds another GET parameter pair to a UrlString.
(<&>) :: (IsString a, Monoid a) => UrlString a -> (a, a) -> UrlString a
-- | Render the Url String flatly - without anything prepended to the
-- target.
expandRelative :: (IsString plain, Monoid plain) => UrlString plain -> plain
-- | Render the Url String as grounded - prepended with a "root"
-- // character.
expandGrounded :: (IsString plain, Monoid plain) => UrlString plain -> plain
-- | Render the Url String as absolute - getting the root from a
-- MonadReader context.
expandAbsolute :: (MonadReader plain m, IsString plain, Monoid plain) => UrlString plain -> m plain
-- | Render the Url String as absolute, but with your own configuration
-- type.
--
--
-- data SiteConfig = SiteConfig { host :: T.Text
-- , cdnHost :: T.Text
-- }
-- deriving (Show, Eq)
--
-- foo :: HtmlT (Reader SiteConfig) ()
-- foo = do
-- url <- lift $ expandAbsoluteWith ("foo.php" <?> ("bar","baz")) host
-- script_ [src_ url] ""
--
-- bar :: LT.Text
-- bar = (runReader (runTextT foo)) $
-- SiteConfig "example.com" "cdn.example.com"
--
expandAbsoluteWith :: (MonadReader a m, IsString plain, Monoid plain) => UrlString plain -> (a -> plain) -> m plain
newtype RelativeUrlT h m b
RelativeUrlT :: (h -> m b) -> RelativeUrlT h m b
runRelativeUrlT :: RelativeUrlT h m b -> h -> m b
type RelativeUrl h b = RelativeUrlT h Identity b
newtype GroundedUrlT h m b
GroundedUrlT :: (h -> m b) -> GroundedUrlT h m b
runGroundedUrlT :: GroundedUrlT h m b -> h -> m b
type GroundedUrl h b = GroundedUrlT h Identity b
newtype AbsoluteUrlT h m b
AbsoluteUrlT :: (h -> m b) -> AbsoluteUrlT h m b
runAbsoluteUrlT :: AbsoluteUrlT h m b -> h -> m b
type AbsoluteUrl h b = AbsoluteUrlT h Identity b
instance Functor m => Functor (RelativeUrlT h m)
instance Functor m => Functor (GroundedUrlT h m)
instance Functor m => Functor (AbsoluteUrlT h m)
instance MonadIO m => MonadIO (AbsoluteUrlT h m)
instance (Monad m, IsString h) => MonadReader h (AbsoluteUrlT h m)
instance MonadTrans (AbsoluteUrlT h)
instance Monad m => Monad (AbsoluteUrlT h m)
instance Applicative f => Applicative (AbsoluteUrlT h f)
instance MonadIO m => MonadIO (GroundedUrlT h m)
instance (Monad m, IsString h) => MonadReader h (GroundedUrlT h m)
instance MonadTrans (GroundedUrlT h)
instance Monad m => Monad (GroundedUrlT h m)
instance Applicative f => Applicative (GroundedUrlT h f)
instance MonadIO m => MonadIO (RelativeUrlT h m)
instance (Monad m, IsString h) => MonadReader h (RelativeUrlT h m)
instance MonadTrans (RelativeUrlT h)
instance Monad m => Monad (RelativeUrlT h m)
instance Applicative f => Applicative (RelativeUrlT h f)
module UrlPath
-- | A UrlReader is a ReaderT monad transformer, that
-- just has conventions associated with it to decide how to "deploy".
--
-- In the sense I'm using here, "deployment" is really "how the hostname
-- gets added to all urls". Change the deployment scheme by
-- coerciing the Monad Reader.
class Url plain m => UrlReader plain (m :: * -> *) where type family Result m :: * -> *
runUrlReader :: (UrlReader plain m, Url plain m) => m b -> plain -> Result m b
-- | 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 (IsString plain, Monoid plain, MonadReader plain m) => Url plain (m :: * -> *)
url :: Url plain m => UrlString plain -> m plain
plainUrl :: Url plain m => plain -> m plain
instance (Monad m, Monoid plain, IsString plain) => UrlReader plain (AbsoluteUrlT plain m)
instance (Monad m, Monoid plain, IsString plain) => Url plain (AbsoluteUrlT plain m)
instance (Monad m, Monoid plain, IsString plain) => UrlReader plain (GroundedUrlT plain m)
instance (Monad m, Monoid plain, IsString plain) => Url plain (GroundedUrlT plain m)
instance (Monad m, Monoid plain, IsString plain) => UrlReader plain (RelativeUrlT plain m)
instance (Monad m, Monoid plain, IsString plain) => Url plain (RelativeUrlT plain m)