Permalink
Browse files

More docs.

  • Loading branch information...
1 parent e7f873d commit d0f0d56fbe1484ff584b1ba2a4db1530e72831ab @sjoerdvisscher sjoerdvisscher committed Dec 9, 2010
Showing with 47 additions and 10 deletions.
  1. +22 −5 Web/Zwaluw.hs
  2. +8 −2 Web/Zwaluw/Core.hs
  3. +13 −1 Web/Zwaluw/Regular.hs
  4. +4 −2 Web/Zwaluw/TH.hs
View
@@ -12,12 +12,14 @@ module Web.Zwaluw (
, parse, unparse
, parse1, unparse1
- -- * Constructing routers
+ -- * Router combinators
, pure, xmap, xmaph
, val, readshow, lit
, opt, duck, satisfy, rFilter, printAs
, manyr, somer, chainr1
, manyl, somel, chainl1
+
+ -- * Built-in routers
, int, string, char, digit, hexDigit
, (/), part
@@ -44,24 +46,33 @@ infixr 8 <>
(<>) = mappend
+-- | Make a router optional.
opt :: Router r r -> Router r r
opt = (id <>)
+-- | Repeat a router zero or more times, combining the results from left to right.
manyr :: Router r r -> Router r r
manyr = opt . somer
+-- | Repeat a router one or more times, combining the results from left to right.
somer :: Router r r -> Router r r
somer p = p . manyr p
+-- | @chainr1 p op@ repeats @p@ one or more times, separated by @op@.
+-- The result is a right associative fold of the results of @p@ with the results of @op@.
chainr1 :: (forall r. Router r (a :- r)) -> (forall r. Router (a :- a :- r) (a :- r)) -> forall r. Router r (a :- r)
chainr1 p op = manyr (p .~ op) . p
+-- | Repeat a router zero or more times, combining the results from right to left.
manyl :: Router r r -> Router r r
manyl = opt . somel
+-- | Repeat a router one or more times, combining the results from right to left.
somel :: Router r r -> Router r r
somel p = p .~ manyl p
+-- | @chainl1 p op@ repeats @p@ one or more times, separated by @op@.
+-- The result is a left associative fold of the results of @p@ with the results of @op@.
chainl1 :: (forall r. Router r (a :- r)) -> (forall r. Router (a :- a :- r) (a :- r)) -> forall r. Router r (a :- r)
chainl1 p op = p .~ manyl (op . duck p)
@@ -103,35 +114,41 @@ digit = xmaph digitToInt (\i -> guard (i >= 0 && i < 10) >> Just (intToDigit i))
hexDigit :: Router r (Int :- r)
hexDigit = xmaph digitToInt (\i -> guard (i >= 0 && i < 16) >> Just (intToDigit i)) (satisfy isHexDigit)
--- | @p / q@ is equivalent to @p . "/" . q@.
infixr 9 /
+-- | @p \/ q@ is equivalent to @p . \"\/\" . q@.
(/) :: Router b c -> Router a b -> Router a c
-f / g = f . lit "/" . g
+(/) f g = f . lit "/" . g
--- | Routes part of a URL, i.e. a String not containing '/' or '?'.
+-- | Routes part of a URL, i.e. a String not containing @\'\/\'@ or @\'\?\'@.
part :: Router r (String :- r)
part = rList (satisfy (\c -> c /= '/' && c /= '?'))
-
rNil :: Router r ([a] :- r)
rNil = pure ([] :-) $ \(xs :- t) -> do [] <- Just xs; Just t
rCons :: Router (a :- [a] :- r) ([a] :- r)
rCons = pure (arg (arg (:-)) (:)) $ \(xs :- t) -> do a:as <- Just xs; Just (a :- as :- t)
+-- | Converts a router for a value @a@ to a router for a list of @a@.
rList :: (forall r. Router r (a :- r)) -> forall r. Router r ([a] :- r)
rList r = manyr (rCons . r) . rNil
rPair :: Router (f :- s :- r) ((f, s) :- r)
rPair = pure (arg (arg (:-)) (,)) $ \(ab :- t) -> do (a,b) <- Just ab; Just (a :- b :- t)
$(deriveRouters ''Either)
+rLeft :: Router (a :- r) (Either a b :- r)
+rRight :: Router (b :- r) (Either a b :- r)
+-- | Combines a router for a value @a@ and a router for a value @b@ into a router for @Either a b@.
rEither :: Router r (a :- r) -> Router r (b :- r) -> Router r (Either a b :- r)
rEither l r = rLeft . l <> rRight . r
$(deriveRouters ''Maybe)
+rNothing :: Router r (Maybe a :- r)
+rJust :: Router (a :- r) (Maybe a :- r)
+-- | Converts a router for a value @a@ to a router for a @Maybe a@.
rMaybe :: Router r (a :- r) -> Router r (Maybe a :- r)
rMaybe r = rJust . r <> rNothing
View
@@ -29,7 +29,8 @@ infixr 8 :-
infixr 9 .~
-
+-- | A @Router a b@ takes an @a@ to parse a URL and results in @b@ if parsing succeeds.
+-- And it takes a @b@ to serialize to a URL and results in @a@ if serializing succeeds.
data Router a b = Router
{ prs :: String -> [(a -> b, String)]
, ser :: b -> [(String -> String, a)] }
@@ -42,6 +43,7 @@ instance Category Router where
(compose (.) pf pg)
(compose (.) sf sg)
+-- | Reverse composition, but with the side effects still in left-to-right order.
(.~) :: Router a b -> Router b c -> Router a c
~(Router pf sf) .~ ~(Router pg sg) = Router
(compose (flip (.)) pf pg)
@@ -127,20 +129,24 @@ duck r = Router
(map (first (\f (h :- t) -> h :- f t)) . prs r)
(\(h :- t) -> map (second (h :-)) $ ser r t)
--- | @r `printAs` s@ uses ther serializer of @r@ to test if serializing succeeds,
+-- | @r \`printAs\` s@ uses ther serializer of @r@ to test if serializing succeeds,
-- and if it does, instead serializes as @s@.
printAs :: Router a b -> String -> Router a b
printAs r s = r { ser = map (first (const (s ++))) . take 1 . ser r }
+-- | Give all possible parses.
parse :: Router () a -> String -> [a]
parse p s = [ a () | (a, "") <- prs p s ]
+-- | Give the first parse, for Routers with a parser that yields just one value.
parse1 :: Router () (a :- ()) -> String -> Maybe a
parse1 p = listToMaybe . map hhead . parse p
+-- | Give all possible serializations.
unparse :: Router () a -> a -> [String]
unparse p = map (($ "") . fst) . ser p
+-- | Give the first serialization, for Routers with a serializer that needs just one value.
unparse1 :: Router () (a :- ()) -> a -> Maybe String
unparse1 p = listToMaybe . unparse p . (:- ())
View
@@ -4,16 +4,28 @@
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE UndecidableInstances #-}
-module Web.Zwaluw.Regular (mkRouters, Routers, RouterList(..), deriveAll, PF) where
+module Web.Zwaluw.Regular
+ ( mkRouters
+ , Routers
+ , RouterList(..)
+
+ -- * Re-exported from Generics.Regular
+ , deriveAll
+ , PF
+ ) where
import Web.Zwaluw.Core
import Generics.Regular
infixr :&
+-- | The type of the list of routers generated for type @r@.
type Routers r = RouterList (PF r) r
+-- | Creates the routers for type @r@, one for each constructor. For example:
+--
+-- @Z rHome :& Z rUserOverview :& Z rUserDetail :& Z rArticle = mkRouters@
mkRouters :: (MkRouters (PF r), Regular r) => Routers r
mkRouters = mkRouters' to (Just . from)
View
@@ -1,14 +1,16 @@
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TemplateHaskell #-}
-module Web.Zwaluw.TH where
+module Web.Zwaluw.TH (deriveRouters) where
import Web.Zwaluw.Core
import Language.Haskell.TH
import Control.Monad
--- Derive routers for all constructors in a datatype.
+-- | Derive routers for all constructors in a datatype. For example:
+--
+-- @$(deriveRouters \'\'Sitemap)@
deriveRouters :: Name -> Q [Dec]
deriveRouters name = do
info <- reify name

0 comments on commit d0f0d56

Please sign in to comment.