Skip to content
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
Cannot retrieve contributors at this time


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.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 ).

Extending Records

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 }

Record Update

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 }

Field Names

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"

> (author' { "Name" = "John" })."Name"

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.