Record literals are surrounded by braces, as in JavaScript:
author :: { name :: String, interests :: Array String }
author =
{ name: "Phil"
, interests: ["Functional Programming", "JavaScript"]
}
Fields of records can be accessed using a dot, followed by the label of the field to access:
> author.name
"Phil"
> author.interests
["Functional Programming","JavaScript"]
{ ... }
is just syntactic sugar for the Record
type constructor, so { language :: String }
is the same as Record ( language :: String )
.
The Record type constructor is parameterized by a row of types. In kind notation, Record
has kind Row Type -> Type
. That is, it takes a row of types to a type.
( language :: String )
denotes a row of types (something of kind Row Type
), so it can be passed to Record
to construct a type, namely Record ( language :: String )
.
It is possible to define an extensible record
type Lang l = { language :: String | l }
that can then be extended like:
type Language = Lang ( country :: String )
The Language
type synonym would then be equivalent to { language :: String, country :: String }
. Note that parentheses must be used for the extension, since l
has to be a row kind not a record type.
Record literals with wildcards can be used to create a function that produces the record instead:
{ foo: _, bar: _ }
is equivalent to:
\foo bar -> { foo: foo, bar: bar }
PureScript also provides a record update syntax similar to Haskell's:
setX :: Number -> Point -> Point
setX val point = point { x = val }
This can be used to update nested records:
setPersonPostcode :: PostCode -> Person -> Person
setPersonPostcode pc p = p { address { postCode = pc } }
A record update function can also be defined by using an _
inplace of the record to be updated like:
_ { fieldName = newValue }
Symbols which are illegal value identifiers, such as title-cased identifiers or ones containing spaces, can be used to identify a field by enclosing it in double-quotes:
author' :: { "Name" :: String, "Personal Interests" :: Array String }
author' = { "Name": "Phil", "Personal Interests": ["Functional Programming", "JavaScript"] }
> author'."Name"
"Phil"
> (author' { "Name" = "John" })."Name"
"John"
If compiling to JavaScript, consider that the PureScript compiler will allow you to choose symbols which have special meaning in JavaScript, like __proto__
.
oops = {__proto__: unsafeCoerce ""}.__proto__.constructor.constructor "alert('lol')" 0
-- When loaded onto a web page, this will display "lol" in a browser dialog box,
-- which is an effectful behavior despite this expression appearing to be pure.