PureScript design FAQ wiki


This post is a wiki! Any user can edit it to contribute!
Add items to this wiki post which you think are common questions about why the PureScript language was designed as it is. Let’s see if people prefer this channel as a means of collecting FAQ items!

Other places in which PureScript Design FAQs are answered:

While it may be best to contribute to existing resources, feel free to edit this post to add more.


(answer here)

Why am I required to choose an instance name for type classes?

Existing discussion: (https://github.com/purescript/purescript/issues/1078, https://github.com/purescript/purescript/issues/952).

Some reasons:

  • The instance names are used to improve the readability of the generated JavaScript.
  • Deterministic names are good and it’s hard to write a function which can produce nice names to use in the compiler. For example, consider the naive algorithm of simply using type class name + type name + type parameter name the instance names of these types instance Functor FooBar Baz and instance Functor Foo BarBaz would collide.
  • Renaming a class or type may break working FFI code.
  • It’s sometimes nice to name an instance differently than the class or type, such as instance refl :: TypeEquals a a.

What’s the difference between a Row and a Record?

  • { title :: String } is the same as Record ( title :: String ). Also, a record has a value level representation: a record with a properties title, while a row is purely a type level construct, having pairs of labels and types. See the documentation on Pursuit: https://pursuit.purescript.org/builtins/docs/Prim#t:Record

  • Speaking about semantics, rows support duplicate labels while records do not. While a record type’s row can have duplicate labels, a record literal can’t be written which satisfies it. The semantics of duplicate labels in records is such that the duplicates are ignored, so it’s hard to do anything useful with playing with that aspect of rows in records.

  • Generally, row types are useful for building and describing other types in a modular way, since they allow labels to be added and removed from them, while following some user defined constraints. For example, libraries like purescript-variant.

Newtyping a Primitive Type vs Using a Primitive Type

See When should you use primitive types instead of custom types?


  • How does do know when you want to use bind? do syntax doesn’t care about types, it just inserts calls to bind and discard, where discard is things which are sequenced that don’t use the <- binder, like x <- y. So, basically do-notation will insert a bind in between each new line in the block.

In compiler error messages, which is expected type and which is actual?

  • In compiler error messages, which is the expected type and which is the actual type in the message “Could not match A with B”? With bidirectional type-checking and type inference, which PureScript uses, it’s tricky to know which is the expected type or the actual type. This question was answered by the compiler maintainers in the past multiple times: purescript/purescript#3399


Performance Considerations

See Performance in Halogen components

Rendering optional attributes/elements

See http://codingstruggles.com/purescript/optiona-elements-halogen.html


IMO, the FAQ should include these things

  • ES6 related things
  • Why type class instances require names
  • How PS differs from Haskell and Why