querystring-pickle: Picklers for de/serialising Generic data types to and from query strings

[ data, library, network, web ] [ Propose Tags ]

Type classes, pickling combinators, and GHC.Generics implementations for Query Strings

[Skip to Readme]




Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


  • No Candidates
Versions [RSS] 0.1.0, 0.1.1, 0.1.2, 0.1.3, 0.1.4, 0.1.5, 0.1.7, 0.1.8, 0.1.9, 0.2.0
Dependencies base (>=4.6 && <5), bytestring, text [details]
License LicenseRef-OtherLicense
Copyright Copyright (c) 2013 Brendan Hay
Author Brendan Hay
Maintainer Brendan Hay <brendan.g.hay@gmail.com>
Category Data, Network, Web
Source repo head: git clone git://github.com/brendanhay/querystring-pickle.git
Uploaded by BrendanHay at 2014-06-23T09:37:15Z
Reverse Dependencies 1 direct, 0 indirect [details]
Downloads 7423 total (17 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Successful builds reported [all 1 reports]

Readme for querystring-pickle-0.2.0

[back to package description]


Build Status

Table of Contents





Common Instances


No default instance for IsQuery a => IsQuery [a] is specified since there are a number of possible implementations. To that end, two pickling combinators are supplied:


A query string of the format ?key=Saab,Audi,Holden can be derived using qpList as follows:

instance IsQuery a => IsQuery [a] where
    queryPickler = qpList queryPickler


Alternatively, a query string of the format key.1=Saab&key.2=Audi&key.3=Holden can be derived using the qpOrdinalList combinator:

instance IsQuery a => IsQuery [a] where
    queryPickler = qpOrdinalList queryPickler

Ordering is preserved in both cases, although qpOrdinalList would preserve the order if the querystring was reshuffled.


IsQuery instances for Maybe a and Either a b are not supplied due to ambiguous semantics, take the following example:

instance IsQuery a => IsQuery (Maybe a) where
    queryPickler = qpOption queryPickler

instance (IsQuery a, IsQuery b) => IsQuery (Either a b) where
    queryPickler = queryPickler `qpEither` queryPickler

data A = A { aInt1 :: Int, aInt2 :: Int } deriving (Show, Generic)
data B = B { bA :: Maybe A } deriving (Show, Generic)
data C = C { cB :: B } deriving (Show, Generic)
data D = D { dAInt :: Either A Int } deriving (Show, Generic)

instance IsQuery A
instance IsQuery B
instance IsQuery C
instance IsQuery D

let c = C $ B Nothing
let d = D . Left $ A 1 2
let e = D $ Right 3

Running toQuery / fromQuery on the example bindings yields:

λ: toQuery c

λ: fromQuery (toQuery c) :: Either String C
Left "qpElem: non-locatable - B - List []"

λ: toQuery d

λ: fromQuery (toQuery d) :: Either String D
Right (D {dAInt = Left (A {aInt1 = 1, aInt2 = 2})})

λ: toQuery e

λ: fromQuery (toQuery e) :: Either String D
Right (D {dAInt = Right 3})

If data type B has a second non-optional field, the fromQuery deserialisation of binding c will succeed.

This is due to the overly simple underlying rose tree used as the intermediate data structure for query transforms. Something that will hopefully be fixed in a future release.

It is left up to the consumer of the library to decide best how to handle this case. I apologies if it forces anyone to use orphaned instances.


Due to the dependency on GHC.Generics a version of base 4.6 or higher is required.


For any problems, comments or feedback please create an issue here on GitHub.


querystring-pickle is released under the Mozilla Public License Version 2.0