Safe Haskell | None |
---|---|
Language | Haskell2010 |
Rowdy is a DSL for defining web routes. The DSL is only a nice syntax for expressing the tree-like structure of routes -- to actually interpret the route into something useful, you'll need another package.
rowdy-yesod
provides a function that converts this representation into the
Yesod route format, allowing you to drop the quasiquotater and use a plain
Haskell DSL.
rowdy-servant
provides a function that converts the DSL into Servant's type
level DSL for defining routes. This allows you to work with a value-level
DSL, taking full advantage of Haskell's value level programming, and then
promote the DSL to the type level using Template Haskell.
- newtype RouteDsl nest capture terminal a = RouteDsl {
- unRouteDsl :: Writer (DForest nest capture terminal) a
- runRouteDsl :: RouteDsl n c e a -> Forest n c e
- runRouteDsl' :: RouteDsl n c e a -> DForest n c e
- pathComponent :: capture -> RouteDsl nest capture endpoint () -> RouteDsl nest capture endpoint ()
- (//) :: capture -> RouteDsl nest capture endpoint () -> RouteDsl nest capture endpoint ()
- nest :: nest -> RouteDsl nest capture endpoint () -> RouteDsl nest capture endpoint ()
- (/:) :: nest -> RouteDsl nest capture endpoint () -> RouteDsl nest capture endpoint ()
- terminal :: endpoint -> RouteDsl nest capture endpoint ()
- unnest :: RouteTree nest capture terminal -> [([capture], terminal)]
- type ForestOf f n capture terminal = f (RouteTree n capture terminal)
- type DForest n c t = ForestOf DList n c t
- type Forest n c t = ForestOf [] n c t
- data RouteTree nest capture terminal
- = Leaf terminal
- | PathComponent capture (RouteTree nest capture terminal)
- | Nest nest [RouteTree nest capture terminal]
Documentation
newtype RouteDsl nest capture terminal a Source #
A RouteDsl
is a type useful for constructing web routes. At it's heart,
it is a DSL for constructing a RouteTree
, and is totally optional.
Routes are defined by how they handle nest
ing, what sorts of values are
used to represent capture
s, and what values are used to represent
endpoints.
Since: 0.0.1.0
RouteDsl | |
|
runRouteDsl :: RouteDsl n c e a -> Forest n c e Source #
runRouteDsl' :: RouteDsl n c e a -> DForest n c e Source #
pathComponent :: capture -> RouteDsl nest capture endpoint () -> RouteDsl nest capture endpoint () Source #
Introduce a capture
into all of the routes defined in the second
argument. This function does not introduce nesting, so multiple distinct
routes will be created.
As an example:
example :: RouteDsl nest String String () example =pathComponent
"hello" $ doterminal
"first route"terminal
"second route"
Calling
will give a data structure like:runRouteDsl
example
[PathComponent
"hello" (Leaf
"first route") ,PathComponent
"hello" (Leaf
"second route") ]
Since: 0.0.1.0
(//) :: capture -> RouteDsl nest capture endpoint () -> RouteDsl nest capture endpoint () infixr 5 Source #
An infix operator for pathComponent
.
Since: 0.0.1.0
nest :: nest -> RouteDsl nest capture endpoint () -> RouteDsl nest capture endpoint () Source #
Introduce a nesting point in the route DSL. While the pathComponent
function adds the capture
to each route defined in the second argument,
this one preserves the tree-like structure of the declaration.
example ::RouteDsl
String String String () example =pathComponent
"thing" $nest
"hello" $ do terminal "first" terminal "second"
Calling
would give a data structure like:runRouteDsl
example
[PathComponent
"thing" (Nest
[ Leaf "first" , Leaf "second" ] ) ]
In constrast, if nest
were not called, you would see the PathComponent
repeated and distributed to both endpoints.
Since: 0.0.1.0
(/:) :: nest -> RouteDsl nest capture endpoint () -> RouteDsl nest capture endpoint () infixr 7 Source #
An infix operator alias for nest
.
Since: 0.0.1.0
terminal :: endpoint -> RouteDsl nest capture endpoint () Source #
Record the given endpoint
as a route.
Since: 0.0.1.0
unnest :: RouteTree nest capture terminal -> [([capture], terminal)] Source #
Convert a RouteTree
into a flattened list of routes. Each terminal
is
paired with the list of capture
s that preceeded it.
Since: 0.0.1.0
type ForestOf f n capture terminal = f (RouteTree n capture terminal) Source #
For efficiency's sake, we encode the route DSL as a DList
while defining
them, and (for convenience's sake) we present them as an ordinary list when
you run it. To prevent type complexity, we parameterize the forest on how
we're working with it.
Since: 0.0.1.0
data RouteTree nest capture terminal Source #
The core data type that is produced by the RouteDsl
. If you'd prefer
a non-monadic interface to creating these, you're welcome to use the
constructors directly.
The DSL defined as example
below has the route representation given by
desugared
:
example ::Forest
String String String example =runRouteDsl
$ do "hello" // doterminal
"world"terminal
"friend" "nest" /: doterminal
"nope"terminal
"yes" desugared ::Forest
String String String desugared = [PathComponent
"hello" (Leaf
"world") ,PathComponent
"hello" (Leaf
"friend") ,PathComponent
"hello" (Nest
"nest" [Leaf
"nope" ,Leaf
"yes" ] ) ]
Since: 0.0.1.0
Leaf terminal | |
PathComponent capture (RouteTree nest capture terminal) | |
Nest nest [RouteTree nest capture terminal] |
Functor (RouteTree nest capture) Source # | |
Foldable (RouteTree nest capture) Source # | |
(Eq nest, Eq capture, Eq terminal) => Eq (RouteTree nest capture terminal) Source # | |
(Show nest, Show capture, Show terminal) => Show (RouteTree nest capture terminal) Source # | |
MonadWriter (DForest nest capture terminal) (RouteDsl nest capture terminal) Source # | |