HList- Heterogeneous lists

Safe HaskellNone






>>> :set -XQuasiQuotes -XViewPatterns
>>> let y = Label :: Label "y"
>>> let x = Label :: Label "x"
>>> [pun| x y |] <- return (x .=. 3 .*. y .=. "hi" .*. emptyRecord)
>>> print (x,y)

Compare with the standard way to construct records above

>>> let x = 3; y = "hi"
>>> [pun|x y|]

Nesting is supported. The idea is that variables inside { } are in another record. More concretely:

[pun| ab@{ a b } y z c{d} |]

as a pattern, it will bindings from an original record x, if you interpret (.) as a left-associative field lookup (as it is in other languages):

let ab = xab
    a = x.ab.a
    b = x.ab.b
    y = x.y
    z = x.z
    -- c is not bound
    d = x.c.d

as an expression, it creates a new record which needs the variables ab a b y z d in-scope. ab needs to be a record, and if it has fields called a or b they are overridden by the values of a and b which are in scope.

( ) parens mean the same thing as { }, except the pattern match restricts the fields in the record supplied to be exactly the ones provided. In other words

[pun| (x _ y{}) |] = list
-- desugars to something like:
Record ((Tagged x :: Tagged "x" s1) `HCons`
        (Tagged _ :: Tagged t   s2) `HCons`
        (Tagged _ :: Tagged "y" s3) `HCons`
         HNil) = list

Where the s1 and s2 are allowed to fit whatever is in the HList. Note that this also introduces the familiar wild card pattern (_), and shows again how to ensure a label is present but not bind a variable to it.

See also examples/pun.hs. In {} patterns, pun can work with Variant too.

pun :: QuasiQuoter Source

requires labels to be promoted strings (kind Symbol), as provided by Data.HList.Label6 (ie. the label for foo is Label :: Label "foo"), or Data.HList.Labelable