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.
ES6
(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 typesinstance Functor FooBar Baz
andinstance 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 asRecord ( title :: String )
. Also, a record has a value level representation: a record with a propertiestitle
, 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?
do-notation
- How does
do
know when you want to use bind?do
syntax doesn’t care about types, it just inserts calls tobind
anddiscard
, wherediscard
is things which are sequenced that don’t use the<-
binder, likex <- y
. So, basically do-notation will insert abind
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
Halogen
Performance Considerations
See Performance in Halogen components
Rendering optional attributes/elements
See http://codingstruggles.com/purescript/optiona-elements-halogen.html