Routing.Duplex
#RouteDuplex
data RouteDuplex i o
The core abstraction of this library. The values of this type can be used both for parsing
values of type o
from String
as well as printing values of type i
into String
.
For most purposes, you'll likely want RouterDuplex'
which uses the same
type for both parameters.
Constructors
RouteDuplex (i -> RoutePrinter) (RouteParser o)
Instances
Functor (RouteDuplex i)
Apply (RouteDuplex i)
Applicative (RouteDuplex i)
Profunctor RouteDuplex
(IsSymbol sym, Cons sym (RouteDuplex String String -> RouteDuplex a b) rx1 r1, Cons sym a rx2 r2, Cons sym b r3 rx3, Lacks sym r3, RouteDuplexBuildParams rest r1 r2 rx3 r4) => RouteDuplexBuildParams (Cons sym (RouteDuplex String String -> RouteDuplex a b) rest) r1 r2 r3 r4
#RouteDuplex'
type RouteDuplex' a = RouteDuplex a a
A type restricted variant of RouteDuplex
where input and output are
the same type. This type will typically be your custom Route
data type
representing valid routes within your application.
#parse
parse :: forall i o. RouteDuplex i o -> String -> Either RouteError o
Uses a given codec to parse a value of type o
out of String representing
the path, query and fragment (hash) of a URI (see
URI - generic syntax)
or produce a RouteError
if parsing fails.
print :: forall i o. RouteDuplex i o -> i -> String
Renders a value of type i
into a String representation of URI path,
query and fragment (hash).
#prefix
prefix :: forall a b. String -> RouteDuplex a b -> RouteDuplex a b
Strips (when parsing) or adds (when printing) a given string segment of the
path. Note: this combinator only deals with a single segment.
If you pass it a string containing '/' it will percent encode it and treat it as single segment.
E.g. prefix "/api/v1"
will attempt to match single segment "%2Fapi%2Fv1"
which is probably not what you want.
See path
if you want to deal with prefixes consisting of multiple segments.
parse (prefix "api" segment) "api/a" == Right "a"
parse (prefix "/api/v1" segment)) "/api/v1/a" == Left (Expected "/api/v1" "")
-- contrast with `path`
parse (path "/api/v1" segment)) "/api/v1/a" == Right "a"
#suffix
suffix :: forall a b. RouteDuplex a b -> String -> RouteDuplex a b
Similar to prefix
. Strips (when parsing) or adds (when printing) a given
string segment from the end of the path. The same precautions for prefix
apply here.
#path
path :: forall a b. String -> RouteDuplex a b -> RouteDuplex a b
Strips (when parsing) or adds (when printing) a given String prefix,
potentially consisting of multiple path segments. Constrast this with prefix
,
which only deals with single segment.
parse (path "/api/v1" segment) "/api/v1/a" == Right "a"
parse (path "/api/v1" segment) "/api/v2/a" == Left (Expected "v1" "v2")
#root
root :: forall a b. RouteDuplex a b -> RouteDuplex a b
Modifies a given codec to require a prefix of '/'. You can think of it as stripping and adding the '/' at the beginning of path, failing if it's not there.
parse (root segment) "/abc" == Right "abc"
parse (root segment) "abc" == Left (Expected "" "abc")
print (root segment) "abc" == "/abc"
#end
end :: forall a b. RouteDuplex a b -> RouteDuplex a b
end codec
will only suceed if codec
succeeds and there are no
additional path segments remaining to be processed.
parse (end segment) "abc" == Right "abc"
parse (end segment) "abc/def" == Left (ExpectedEndOfPath "def")
#segment
segment :: RouteDuplex' String
Consumes or prints a single path segment. Note: URI encoding and decoding is done automatically.
parse segment "abc" == Right "abc"
parse segment "abc%20def" == Right "abc def" -- automatic decoding of uri components
parse segment "abc/def" == Right "abc"
parse segment "/abc" == Right "" -- the empty string before the first '/'
parse (root segment) "/abc" == Right "abc"
print segment "hello there" == "hello%20there"
print segment "" == "/"
#param
param :: String -> RouteDuplex' String
param name
consumes or prints a query parameter with the given name
.
Parsing will fail if the parameter is not there.
parse (param "search") "?search=keyword" == Right "keyword"
parse (param "search") "/" == Left (MissingParam "search")
parse (optional (param "search")) "/" == Right Nothing
#flag
flag :: RouteDuplex' String -> RouteDuplex' Boolean
Consumes or prints a query flag (i.e. parameter without value).
Note: that this combinator ignores the value of the parameter. It only cares about its presence/absence.
Presence is interpreted as true
, absence as false
.
parse (flag (param "x")) "?x" == Right true
parse (flag (param "x")) "?x=true", == Right true
parse (flag (param "x")) "?x=false", == Right true -- value is ignored, what matters is presence of the parameter x
parse (flag (param "x")) "?y", == Right false
#many1
many1 :: forall f a b. Foldable f => Alt f => Applicative f => RouteDuplex a b -> RouteDuplex (f a) (f b)
Repeatedly applies a given codec to parse one or more values from path segments. Parsing will fail if no segment can be parsed.
parse (many1 (int segment)) "1/2/3/x" == Right [1,2,3]
parse (many1 (int segment)) "x", == Left (Expected "Int" "x") :: Either RouteError (Array Int)
#many
many :: forall f a b. Foldable f => Alternative f => RouteDuplex a b -> RouteDuplex (f a) (f b)
Similar to many1
, except also succeeds when no values can be parsed.
parse (many (int segment)) "1/2/3/x" == Right [1,2,3]
parse (many (int segment)) "x", == Right []
#rest
rest :: RouteDuplex' (Array String)
Consumes or prints all the remaining segments.
parse rest "" == Right []
parse (path "a/b" rest) "a/b/c/d" == Right ["c", "d"]
print rest ["a", "b"] == "a/b"
#default
default :: forall a b. b -> RouteDuplex a b -> RouteDuplex a b
Sets a default value which will be returned when parsing fails. Does not influence printing in any way.
parse (default 0 $ int segment) "1" == Right 1
parse (default 0 $ int segment) "x" == Right 0
#optional
optional :: forall a b. RouteDuplex a b -> RouteDuplex (Maybe a) (Maybe b)
Augments the behavior of a given codec by making it return Nothing
if parsing
fails, or Just value
if it succeeds.
parse (optional segment) "a" == Right (Just "a")
parse (optional segment) "" == Right Nothing
print (optional segment) (Just "a") == "a"
print (optional segment) Nothing == ""
#as
as :: forall s a b. (a -> s) -> (String -> Either String b) -> RouteDuplex s String -> RouteDuplex a b
Builds a codec for a custom type out of printer and parser functions.
data Sort = Asc | Desc
sortToString :: Sort -> String
sortToString = case _ of
Asc -> "asc"
Desc -> "desc"
sortFromString :: String -> Either String Sort
sortFromString = case _ of
"asc" -> Right Asc
"desc" -> Right Desc
val -> Left $ "Not a sort: " <> val
sort :: RouteDuplex' String -> RouteDuplex' Sort
sort = as sortToString sortFromString
#int
int :: RouteDuplex' String -> RouteDuplex' Int
Refines a codec of Strings to Ints.
parse (int segment) "1" == Right 1
parse (int segment) "x" == Left (Expected "Int" "x")
print (int segment) 1 == "1"
#boolean
boolean :: RouteDuplex' String -> RouteDuplex' Boolean
Refines a codec of Strings to Booleans, where true
and false
are the
strings "true"
and "false"
, and other strings are rejected.
parse (boolean segment) "true" == Right true
parse (boolean segment) "x" == Left (Expected "Boolean" "x")
print (boolean segment) true == "true"
#string
string :: RouteDuplex' String -> RouteDuplex' String
This does nothing (internally it's defined as identity).
It can be used to restrict a type parameter of a polymorphic RouteDuplex' a
to String
.
#record
record :: forall r. RouteDuplex r (Record ())
Combined with prop
or :=
, builds a Record where the order of
parsing and printing matters.
date =
record
# prop (SProxy :: _ "year") (int segment)
# prop (SProxy :: _ "month") (int segment)
# prop (SProxy :: _ "day") (int segment)
parse (path "blog" date) "blog/2019/1/2" ==
Right { year: 2019, month: 1, day: 2 }
#prop
prop :: forall sym a b r1 r2 r3 rx. IsSymbol sym => Cons sym a rx r1 => Cons sym b r2 r3 => Lacks sym r2 => SProxy sym -> RouteDuplex a b -> RouteDuplex (Record r1) (Record r2) -> RouteDuplex (Record r1) (Record r3)
See record
.
#(:=)
Operator alias for Routing.Duplex.prop (non-associative / precedence 2)
#RouteDuplexParams
class RouteDuplexParams :: Row Type -> Row Type -> Constraint
class RouteDuplexParams (r1 :: Row Type) (r2 :: Row Type) | r1 -> r2 where
Members
params :: Record r1 -> RouteDuplex' (Record r2)
Instances
(RowToList r1 rl, RouteDuplexBuildParams rl r1 r2 () r2) => RouteDuplexParams r1 r2
#RouteDuplexBuildParams
class RouteDuplexBuildParams :: RowList Type -> Row Type -> Row Type -> Row Type -> Row Type -> Constraint
class RouteDuplexBuildParams (rl :: RowList Type) (r1 :: Row Type) (r2 :: Row Type) (r3 :: Row Type) (r4 :: Row Type) | rl -> r1 r2 r3 r4 where
Members
buildParams :: RLProxy rl -> Record r1 -> RouteDuplex (Record r2) (Record r3) -> RouteDuplex (Record r2) (Record r4)
Instances
(IsSymbol sym, Cons sym (RouteDuplex String String -> RouteDuplex a b) rx1 r1, Cons sym a rx2 r2, Cons sym b r3 rx3, Lacks sym r3, RouteDuplexBuildParams rest r1 r2 rx3 r4) => RouteDuplexBuildParams (Cons sym (RouteDuplex String String -> RouteDuplex a b) rest) r1 r2 r3 r4
RouteDuplexBuildParams Nil r1 r2 r3 r3
Modules
- Attribute
- Control.Alt
- Control.Alternative
- Control.Applicative
- Control.Apply
- Control.Biapplicative
- Control.Biapply
- Control.Bind
- Control.Category
- Control.Comonad
- Control.Comonad.Cofree
- Control.Comonad.Cofree.Class
- Control.Comonad.Env
- Control.Comonad.Env.Class
- Control.Comonad.Env.Trans
- Control.Comonad.Store
- Control.Comonad.Store.Class
- Control.Comonad.Store.Trans
- Control.Comonad.Traced
- Control.Comonad.Traced.Class
- Control.Comonad.Traced.Trans
- Control.Comonad.Trans.Class
- Control.Extend
- Control.Lazy
- Control.Monad
- Control.Monad.Cont
- Control.Monad.Cont.Class
- Control.Monad.Cont.Trans
- Control.Monad.Error.Class
- Control.Monad.Except
- Control.Monad.Except.Trans
- Control.Monad.Free
- Control.Monad.Free.Class
- Control.Monad.Gen
- Control.Monad.Gen.Class
- Control.Monad.Gen.Common
- Control.Monad.Identity.Trans
- Control.Monad.List.Trans
- Control.Monad.Maybe.Trans
- Control.Monad.RWS
- Control.Monad.RWS.Trans
- Control.Monad.Reader
- Control.Monad.Reader.Class
- Control.Monad.Reader.Trans
- Control.Monad.Rec.Class
- Control.Monad.State
- Control.Monad.State.Class
- Control.Monad.State.Trans
- Control.Monad.Trampoline
- Control.Monad.Trans.Class
- Control.Monad.Writer
- Control.Monad.Writer.Class
- Control.Monad.Writer.Trans
- Control.MonadPlus
- Control.MonadZero
- Control.Parallel
- Control.Parallel.Class
- Control.Plus
- Control.Semigroupoid
- ConvertableOptions
- Cowboy.Static
- Data.Align
- Data.Array
- Data.Array.NonEmpty
- Data.Array.NonEmpty.Internal
- Data.Array.Partial
- Data.Bifoldable
- Data.Bifunctor
- Data.Bifunctor.Join
- Data.Bitraversable
- Data.Boolean
- Data.BooleanAlgebra
- Data.Bounded
- Data.Bounded.Generic
- Data.CatList
- Data.CatQueue
- Data.Char
- Data.Char.Gen
- Data.CodePoint.Unicode
- Data.CodePoint.Unicode.Internal
- Data.CodePoint.Unicode.Internal.Casing
- Data.CommutativeRing
- Data.Compactable
- Data.Comparison
- Data.Const
- Data.Coyoneda
- Data.Date
- Data.Date.Component
- Data.Date.Component.Gen
- Data.Date.Gen
- Data.DateTime
- Data.DateTime.Gen
- Data.DateTime.Instant
- Data.DateTime.Parsing
- Data.Decidable
- Data.Decide
- Data.Distributive
- Data.Divide
- Data.Divisible
- Data.DivisionRing
- Data.Either
- Data.Either.Inject
- Data.Either.Nested
- Data.Enum
- Data.Enum.Gen
- Data.Enum.Generic
- Data.Eq
- Data.Eq.Generic
- Data.Equivalence
- Data.EuclideanRing
- Data.Exists
- Data.Field
- Data.Filterable
- Data.FingerTree
- Data.FingerTree.Digit
- Data.Foldable
- Data.FoldableWithIndex
- Data.Formatter.DateTime
- Data.Formatter.Internal
- Data.Formatter.Interval
- Data.Formatter.Number
- Data.Formatter.Parser.Interval
- Data.Formatter.Parser.Number
- Data.Formatter.Parser.Utils
- Data.Function
- Data.Function.Uncurried
- Data.Functor
- Data.Functor.App
- Data.Functor.Clown
- Data.Functor.Compose
- Data.Functor.Contravariant
- Data.Functor.Coproduct
- Data.Functor.Coproduct.Inject
- Data.Functor.Coproduct.Nested
- Data.Functor.Costar
- Data.Functor.Flip
- Data.Functor.Invariant
- Data.Functor.Joker
- Data.Functor.Product
- Data.Functor.Product.Nested
- Data.Functor.Product2
- Data.Functor.Variant
- Data.FunctorWithIndex
- Data.Generic.Rep
- Data.Graph
- Data.HeytingAlgebra
- Data.HeytingAlgebra.Generic
- Data.Identity
- Data.Int
- Data.Int.Bits
- Data.Interval
- Data.Interval.Duration
- Data.Interval.Duration.Iso
- Data.Lazy
- Data.Lens
- Data.Lens.AffineTraversal
- Data.Lens.At
- Data.Lens.Common
- Data.Lens.Fold
- Data.Lens.Fold.Partial
- Data.Lens.Getter
- Data.Lens.Grate
- Data.Lens.Index
- Data.Lens.Indexed
- Data.Lens.Internal.Bazaar
- Data.Lens.Internal.Exchange
- Data.Lens.Internal.Focusing
- Data.Lens.Internal.Forget
- Data.Lens.Internal.Grating
- Data.Lens.Internal.Indexed
- Data.Lens.Internal.Market
- Data.Lens.Internal.Re
- Data.Lens.Internal.Shop
- Data.Lens.Internal.Stall
- Data.Lens.Internal.Tagged
- Data.Lens.Internal.Wander
- Data.Lens.Internal.Zipping
- Data.Lens.Iso
- Data.Lens.Iso.Newtype
- Data.Lens.Lens
- Data.Lens.Lens.Product
- Data.Lens.Lens.Tuple
- Data.Lens.Lens.Unit
- Data.Lens.Lens.Void
- Data.Lens.Prism
- Data.Lens.Prism.Coproduct
- Data.Lens.Prism.Either
- Data.Lens.Prism.Maybe
- Data.Lens.Record
- Data.Lens.Setter
- Data.Lens.Traversal
- Data.Lens.Types
- Data.Lens.Zoom
- Data.List
- Data.List.Internal
- Data.List.Lazy
- Data.List.Lazy.NonEmpty
- Data.List.Lazy.Types
- Data.List.NonEmpty
- Data.List.Partial
- Data.List.Types
- Data.List.ZipList
- Data.Map
- Data.Map.Gen
- Data.Map.Internal
- Data.Maybe
- Data.Maybe.First
- Data.Maybe.Last
- Data.MediaType
- Data.MediaType.Common
- Data.Monoid
- Data.Monoid.Additive
- Data.Monoid.Alternate
- Data.Monoid.Conj
- Data.Monoid.Disj
- Data.Monoid.Dual
- Data.Monoid.Endo
- Data.Monoid.Generic
- Data.Monoid.Multiplicative
- Data.NaturalTransformation
- Data.Newtype
- Data.NonEmpty
- Data.Nullable
- Data.Number
- Data.Number.Approximate
- Data.Number.Format
- Data.Op
- Data.Ord
- Data.Ord.Down
- Data.Ord.Generic
- Data.Ord.Max
- Data.Ord.Min
- Data.Ordering
- Data.Predicate
- Data.Profunctor
- Data.Profunctor.Choice
- Data.Profunctor.Closed
- Data.Profunctor.Cochoice
- Data.Profunctor.Costrong
- Data.Profunctor.Join
- Data.Profunctor.Split
- Data.Profunctor.Star
- Data.Profunctor.Strong
- Data.Ratio
- Data.Rational
- Data.Ring
- Data.Ring.Generic
- Data.Semigroup
- Data.Semigroup.First
- Data.Semigroup.Foldable
- Data.Semigroup.Generic
- Data.Semigroup.Last
- Data.Semigroup.Traversable
- Data.Semiring
- Data.Semiring.Free
- Data.Semiring.Generic
- Data.Sequence
- Data.Sequence.Internal
- Data.Sequence.NonEmpty
- Data.Sequence.Ordered
- Data.Set
- Data.Set.NonEmpty
- Data.Show
- Data.Show.Generic
- Data.String
- Data.String.CaseInsensitive
- Data.String.CodePoints
- Data.String.CodeUnits
- Data.String.Common
- Data.String.Gen
- Data.String.NonEmpty
- Data.String.NonEmpty.CaseInsensitive
- Data.String.NonEmpty.CodePoints
- Data.String.NonEmpty.CodeUnits
- Data.String.NonEmpty.Internal
- Data.String.Pattern
- Data.String.Regex
- Data.String.Regex.Flags
- Data.String.Regex.Unsafe
- Data.String.Unicode
- Data.String.Unsafe
- Data.Symbol
- Data.These
- Data.These.Gen
- Data.Time
- Data.Time.Component
- Data.Time.Component.Gen
- Data.Time.Duration
- Data.Time.Duration.Gen
- Data.Time.Gen
- Data.Traversable
- Data.Traversable.Accum
- Data.Traversable.Accum.Internal
- Data.TraversableWithIndex
- Data.Tuple
- Data.Tuple.Nested
- Data.Undefinable
- Data.Unfoldable
- Data.Unfoldable1
- Data.Unit
- Data.Validation.Semigroup
- Data.Validation.Semiring
- Data.Variant
- Data.Variant.Internal
- Data.Void
- Data.Witherable
- Data.Yoneda
- Debug
- Effect
- Effect.Class
- Effect.Class.Console
- Effect.Console
- Effect.Exception
- Effect.Exception.Unsafe
- Effect.Random
- Effect.Ref
- Effect.Uncurried
- Effect.Unsafe
- Erl.Atom
- Erl.Atom.Symbol
- Erl.Cowboy
- Erl.Cowboy.Handler
- Erl.Cowboy.Handlers.Common
- Erl.Cowboy.Handlers.Loop
- Erl.Cowboy.Handlers.Rest
- Erl.Cowboy.Handlers.Simple
- Erl.Cowboy.Handlers.WebSocket
- Erl.Cowboy.Req
- Erl.Cowboy.Req.Monad
- Erl.Cowboy.Routes
- Erl.Data.Binary
- Erl.Data.Binary.IOData
- Erl.Data.Binary.IOList
- Erl.Data.Binary.Type
- Erl.Data.Binary.UTF16
- Erl.Data.Binary.UTF32
- Erl.Data.Binary.UTF8
- Erl.Data.Bitstring
- Erl.Data.Bitstring.Type
- Erl.Data.Jsone
- Erl.Data.Jsone.Decode
- Erl.Data.Jsone.Decode.Class
- Erl.Data.Jsone.Decode.Combinators
- Erl.Data.Jsone.Encode
- Erl.Data.Jsone.Encode.Class
- Erl.Data.Jsone.Encode.Combinators
- Erl.Data.Jsone.Parser
- Erl.Data.Jsone.Printer
- Erl.Data.List
- Erl.Data.List.NonEmpty
- Erl.Data.List.Types
- Erl.Data.Map
- Erl.Data.Queue
- Erl.Data.Queue.Types
- Erl.Data.Tuple
- Erl.File
- Erl.FileLib
- Erl.Gun
- Erl.Gun.WsGun
- Erl.Kernel.Application
- Erl.Kernel.Erlang
- Erl.Kernel.Ets
- Erl.Kernel.Exceptions
- Erl.Kernel.File
- Erl.Kernel.Inet
- Erl.Kernel.Os
- Erl.Kernel.Tcp
- Erl.Kernel.Time
- Erl.Kernel.Udp
- Erl.ModuleName
- Erl.ModuleName.Symbol
- Erl.Otp.Types.Crypto
- Erl.Otp.Types.PublicKey
- Erl.Otp.Types.Stdlib
- Erl.Process
- Erl.Process.Raw
- Erl.Ranch
- Erl.Ranch.Transport
- Erl.Ssl
- Erl.StandardResult
- Erl.Test.EUnit
- Erl.Tests.EUnit.Discovery
- Erl.Types
- Erl.Untagged.Union
- ExpectInferred
- Foreign
- Foreign.Index
- Foreign.Keys
- Heterogeneous.Folding
- Heterogeneous.Mapping
- JSURI
- Lager
- Logger
- Math
- NativeRef
- OpenTelemetry
- OpenTelemetry.Metrics
- OpenTelemetry.Metrics.Counter
- OpenTelemetry.Metrics.Meter
- OpenTelemetry.Metrics.SumObserver
- OpenTelemetry.Metrics.UpDownCounter
- OpenTelemetry.Metrics.UpDownSumObserver
- OpenTelemetry.Metrics.ValueObserver
- OpenTelemetry.Metrics.ValueRecorder
- OpenTelemetry.Tracing
- OpenTelemetry.Tracing.Baggage
- OpenTelemetry.Tracing.Ctx
- OpenTelemetry.Tracing.Propagator.TextMap
- OpenTelemetry.Tracing.Span
- OpenTelemetry.Tracing.Tracer
- PSCI.Support
- Partial
- Partial.Unsafe
- Pathy
- Pathy.Gen
- Pathy.Name
- Pathy.Parser
- Pathy.Path
- Pathy.Phantom
- Pathy.Printer
- Pathy.Sandboxed
- Pinto
- Pinto.App
- Pinto.GenServer
- Pinto.GenStatem
- Pinto.MessageRouting
- Pinto.ModuleNames
- Pinto.Monitor
- Pinto.Supervisor
- Pinto.Supervisor.SimpleOneForOne
- Pinto.Timer
- Pinto.Types
- Prelude
- Prim
- Prim.Boolean
- Prim.Coerce
- Prim.Int
- Prim.Ordering
- Prim.Row
- Prim.RowList
- Prim.Symbol
- Prim.TypeError
- PureScript.Metadata
- Random.LCG
- Record
- Record.Builder
- Record.Prefix
- Record.Unsafe
- Record.Unsafe.Union
- Routing.Duplex
- Routing.Duplex.Generic
- Routing.Duplex.Generic.Syntax
- Routing.Duplex.Parser
- Routing.Duplex.Printer
- Routing.Duplex.Types
- RoutingDuplexMiddleware
- Safe.Coerce
- Simple.JSON
- Simple.JSON.Generics
- Simple.JSON.Generics.EnumSumRep
- Simple.JSON.Generics.TaggedSumRep
- Simple.JSON.Generics.UntaggedProductRep
- Simple.JSON.Generics.UntaggedSumRep
- SimpleBus
- Stetson
- Stetson.HandlerProxy
- Stetson.Loop
- Stetson.ModuleNames
- Stetson.Rest
- Stetson.Routing
- Stetson.Types
- Stetson.Utils
- Stetson.WebSocket
- Test.Assert
- Test.QuickCheck
- Test.QuickCheck.Arbitrary
- Test.QuickCheck.Gen
- Test.QuickCheck.Laws
- Test.QuickCheck.Laws.Control
- Test.QuickCheck.Laws.Control.Align
- Test.QuickCheck.Laws.Control.Alignable
- Test.QuickCheck.Laws.Control.Alt
- Test.QuickCheck.Laws.Control.Alternative
- Test.QuickCheck.Laws.Control.Applicative
- Test.QuickCheck.Laws.Control.Apply
- Test.QuickCheck.Laws.Control.Bind
- Test.QuickCheck.Laws.Control.Category
- Test.QuickCheck.Laws.Control.Comonad
- Test.QuickCheck.Laws.Control.Crosswalk
- Test.QuickCheck.Laws.Control.Extend
- Test.QuickCheck.Laws.Control.Monad
- Test.QuickCheck.Laws.Control.MonadPlus
- Test.QuickCheck.Laws.Control.MonadZero
- Test.QuickCheck.Laws.Control.Plus
- Test.QuickCheck.Laws.Control.Semigroupoid
- Test.QuickCheck.Laws.Data
- Test.QuickCheck.Laws.Data.BooleanAlgebra
- Test.QuickCheck.Laws.Data.Bounded
- Test.QuickCheck.Laws.Data.BoundedEnum
- Test.QuickCheck.Laws.Data.CommutativeRing
- Test.QuickCheck.Laws.Data.DivisionRing
- Test.QuickCheck.Laws.Data.Eq
- Test.QuickCheck.Laws.Data.EuclideanRing
- Test.QuickCheck.Laws.Data.Field
- Test.QuickCheck.Laws.Data.Foldable
- Test.QuickCheck.Laws.Data.Functor
- Test.QuickCheck.Laws.Data.FunctorWithIndex
- Test.QuickCheck.Laws.Data.HeytingAlgebra
- Test.QuickCheck.Laws.Data.Monoid
- Test.QuickCheck.Laws.Data.Ord
- Test.QuickCheck.Laws.Data.Ring
- Test.QuickCheck.Laws.Data.Semigroup
- Test.QuickCheck.Laws.Data.Semiring
- Text.Parsing.Indent
- Text.Parsing.Parser
- Text.Parsing.Parser.Combinators
- Text.Parsing.Parser.Expr
- Text.Parsing.Parser.Language
- Text.Parsing.Parser.Pos
- Text.Parsing.Parser.String
- Text.Parsing.Parser.Token
- Tracing.Attributes
- Type.Data.Boolean
- Type.Data.Ordering
- Type.Data.Row
- Type.Data.RowList
- Type.Data.Symbol
- Type.Equality
- Type.Function
- Type.Prelude
- Type.Proxy
- Type.Row
- Type.Row.Homogeneous
- Type.RowList
- URI
- URI.AbsoluteURI
- URI.Authority
- URI.Common
- URI.Extra.MultiHostPortPair
- URI.Extra.QueryPairs
- URI.Extra.UserPassInfo
- URI.Fragment
- URI.HierarchicalPart
- URI.Host
- URI.Host.Gen
- URI.Host.IPv4Address
- URI.Host.IPv6Address
- URI.Host.RegName
- URI.HostPortPair
- URI.HostPortPair.Gen
- URI.Path
- URI.Path.Absolute
- URI.Path.NoScheme
- URI.Path.Rootless
- URI.Path.Segment
- URI.Port
- URI.Port.Gen
- URI.Query
- URI.RelativePart
- URI.RelativeRef
- URI.Scheme
- URI.Scheme.Common
- URI.URI
- URI.URIRef
- URI.UserInfo
- Unsafe.Coerce
- Unsafe.Reference
Builds a
RouteDuplex
from a record of query parameter parsers/printers, where each property corresponds to a query parameter with the same name.