diff --git a/misc_docs/syntax/language_spreads.mdx b/misc_docs/syntax/language_spreads.mdx new file mode 100644 index 000000000..c3fc5cec0 --- /dev/null +++ b/misc_docs/syntax/language_spreads.mdx @@ -0,0 +1,162 @@ +--- +id: "spreads" +keywords: ["spread", "record", "variant", "polymorphic", "array", "list", "function", "partial"] +name: "..." +summary: "This is the `...` syntax." +category: "languageconstructs" +--- + +A `spread` is three dots in a row: `...`. Spreads have many different uses in ReScript depending on in which context it is used. +## Record definitions +> Available in v10+ + +Spreads can be used to copy fields from one record definition into another. + +```res +type a = { + id: string, + name: string, +} + +type b = { + age: int +} + +type c = { + ...a, + ...b, + active: bool +} +``` + +Read more about [record type spreads here](record.md#record-type-spread). + +## Record immutable update +Spreads can be used for immutable updates of records: + +```res +let meNextYear = {...me, age: me.age + 1} +``` + +Read more about [record immutable updates here](record.md#immutable-update). + +## Variant definitions +> Available in v11+ + +Spreads can be used to copy constructors from one variant definition to another. + +```res +type a = One | Two | Three +type b = | ...a | Four | Five +// b is now One | Two | Three | Four | Five +``` + +Read more about [variant type spreads](variant.md#variant-type-spreads) here. + +## Variant pattern matching +> Available in v12+ + +You can refine the type of a variant by spreading compatible a variant when pattern matching: +```res +type pets = Cat | Dog +type fish = Cod | Salmon +type animals = | ...pets | ...fish + +let isPet = (animal: animals) => { + switch animal { + | ...dog => Console.log("A dog!") + | _ => Console.log("Not a dog...") + } +} + +``` + +Read more about [variant type spreads in pattern matching](pattern-matching-destructuring.md#match-on-subtype-variants). + +## Polymorphic variant pattern matching +You can refine compatible polymorphic variants when pattern matching: + +```res +type red = [#Ruby | #Redwood | #Rust] +type blue = [#Sapphire | #Neon | #Navy] + +// Contains all constructors of red and blue. +// Also adds #Papayawhip +type color = [red | blue | #Papayawhip] + +let myColor: color = #Ruby + +switch myColor { +| #...blue => Console.log("This blue-ish") +| #...red => Console.log("This red-ish") +| other => Console.log2("Other color than red and blue: ", other) +} +``` + +Read more about [pattern matching and polymorphic variants](polymorphic-variant.md#combine-types-and-pattern-match). + +## List immutable update +Spreads can be used for immutable updates of lists: + +```res +let prepended = list{1, ...someOtherList} + +// You can spread several lists, but it's O(n) so avoid it if possible +let multiple = list{1, ...prepended, ...anotherList} +``` + +Read more about [immutable list updates](array-and-list.md#immutable-prepend) here. + +## List pattern matching +Spreads can be used when pattern matching on lists: + +```res +let rec printStudents = (students) => { + switch students { + | list{} => () // done + | list{student} => Console.log("Last student: " ++ student) + | list{student1, ...otherStudents} => + Console.log(student1) + printStudents(otherStudents) + } +} +printStudents(list{"Jane", "Harvey", "Patrick"}) +``` + +Read more about [pattern matching on lists](pattern-matching-destructuring.md#match-on-list). + +## Array immutable update +> Available in v11+ + +You can use spreads to add the contents of one array to another, just like in JavaScript: + +```res +let firstArray = [1, 2, 3] +let secondArray = [...firstArray, 4, 5] +``` + +Read more about [array spreads](array-and-list.md#array-spreads). + +## Partial application of functions +> Available in v11+ (uncurried mode) + +You can partially apply a function using the spread syntax. Partially applying a function will return a new function taking only the arguments that wasn't applied partially. + +```res +let add = (a, b) => a + b +let addFive = add(5, ...) +``` + +Read more about [partial application of functions](function.md#partial-application). + +### References + +* [Record type spreads](record.md#record-type-spread) +* [Record immutable updates](record.md#immutable-update) +* [Variant type spreads](variant.md#variant-type-spreads) +* [Variant type spreads in pattern matching](pattern-matching-destructuring.md#match-on-subtype-variants) +* [Pattern matching and polymorphic variants](polymorphic-variant.md#combine-types-and-pattern-match) +* [List immutable updates](array-and-list.md#immutable-prepend) +* [List pattern matching](pattern-matching-destructuring.md#match-on-list) +* [Array spreads](array-and-list.md#array-spreads) +* [Partial application of functions](function.md#partial-application) \ No newline at end of file