mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
Update some more docs
This commit is contained in:
parent
4e9b11afd4
commit
2b2b6e3ddd
8 changed files with 255 additions and 104 deletions
|
@ -67,11 +67,11 @@ xor : Bool, Bool -> Bool
|
||||||
##
|
##
|
||||||
## Structural equality works as follows:
|
## Structural equality works as follows:
|
||||||
##
|
##
|
||||||
## 1. #Int and #Float values are equal if their numbers are equal.
|
## 1. Global tags are equal if they are the same tag, and also their contents (if any) are equal.
|
||||||
## 2. Records are equal if all their fields are equal.
|
## 2. Private tags are equal if they are the same tag, in the same module, and also their contents (if any) are equal.
|
||||||
## 3. Global tags are equal if they are the same tag, and also their contents (if any) are equal.
|
## 3. Records are equal if all their fields are equal.
|
||||||
## 4. Private tags are equal if they are the same tag, in the same module, and also their contents (if any) are equal.
|
## 4. Collections ([Str], [List], [Dict], and [Set]) are equal if they are the same length, and also all their corresponding elements are equal.
|
||||||
## 5. Collections (#String, #List, #Map, #Set, and #Bytes) are equal if they are the same length, and also all their corresponding elements are equal.
|
## 5. #Num values are equal if their numbers are equal, with one exception: if both arguments to `isEq` are *NaN*, then `isEq` returns `False`. See [Num.isNaN] for more about *NaN*.
|
||||||
##
|
##
|
||||||
## Note that `isEq` takes `'val` instead of `val`, which means `isEq` does not
|
## Note that `isEq` takes `'val` instead of `val`, which means `isEq` does not
|
||||||
## accept arguments whose types contain functions.
|
## accept arguments whose types contain functions.
|
||||||
|
|
|
@ -27,5 +27,7 @@ map :
|
||||||
|
|
||||||
# TODO: removed `'` from signature because parser does not support it yet
|
# TODO: removed `'` from signature because parser does not support it yet
|
||||||
# Original signature: insert : Dict 'key val, 'key, val -> Dict 'key val
|
# Original signature: insert : Dict 'key val, 'key, val -> Dict 'key val
|
||||||
## Since NaN is defined to be unequal to NaN, panics if given NaN for a key.
|
## Make sure never to insert a key of *NaN* into a [Dict]! Becuase *NaN* is
|
||||||
|
## defined to be unequal to *NaN*, inserting a *NaN* key results in an entry
|
||||||
|
## that can never be retrieved or removed from the [Dict].
|
||||||
insert : Dict key val, key, val -> Dict key val
|
insert : Dict key val, key, val -> Dict key val
|
||||||
|
|
|
@ -232,9 +232,28 @@ reverse : List elem -> List elem
|
||||||
|
|
||||||
## Sorts a list using a function which specifies how two elements are ordered.
|
## Sorts a list using a function which specifies how two elements are ordered.
|
||||||
##
|
##
|
||||||
##
|
## When sorting by numeric values, it's more efficient to use [sortAsc] or
|
||||||
|
## [sortDesc] instead.
|
||||||
sort : List elem, (elem, elem -> [ Lt, Eq, Gt ]) -> List elem
|
sort : List elem, (elem, elem -> [ Lt, Eq, Gt ]) -> List elem
|
||||||
|
|
||||||
|
## Sorts a list in ascending order (lowest to highest), using a function which
|
||||||
|
## specifies a way to represent each element as a number.
|
||||||
|
##
|
||||||
|
## This is more efficient than [sort] because it skips
|
||||||
|
## calculating the `[ Lt, Eq, Gt ]` value and uses the number directly instead.
|
||||||
|
##
|
||||||
|
## To sort in descending order (highest to lowest), use [List.sortDesc] instead.
|
||||||
|
sortAsc : List elem, (elem -> Num *) -> List elem
|
||||||
|
|
||||||
|
## Sorts a list in descending order (highest to lowest), using a function which
|
||||||
|
## specifies a way to represent each element as a number.
|
||||||
|
##
|
||||||
|
## This is more efficient than [sort] because it skips
|
||||||
|
## calculating the `[ Lt, Eq, Gt ]` value and uses the number directly instead.
|
||||||
|
##
|
||||||
|
## To sort in ascending order (lowest to highest), use [List.sortAsc] instead.
|
||||||
|
sortDesc : List elem, (elem -> Num *) -> List elem
|
||||||
|
|
||||||
## Convert each element in the list to something new, by calling a conversion
|
## Convert each element in the list to something new, by calling a conversion
|
||||||
## function on each of them. Then return a new list of the converted values.
|
## function on each of them. Then return a new list of the converted values.
|
||||||
##
|
##
|
||||||
|
|
|
@ -122,6 +122,30 @@ Dec : Frac [ @Decimal128 ]
|
||||||
## been done in a base-2 floating point calculation, which causes noticeable
|
## been done in a base-2 floating point calculation, which causes noticeable
|
||||||
## precision loss in this case.
|
## precision loss in this case.
|
||||||
##
|
##
|
||||||
|
## The floating-point numbers ([F32] and [F64]) also have three values which
|
||||||
|
## are not ordinary [finite numbers](https://en.wikipedia.org/wiki/Finite_number).
|
||||||
|
## They are:
|
||||||
|
## * ∞ ([infinity](https://en.wikipedia.org/wiki/Infinity))
|
||||||
|
## * -∞ (negative infinity)
|
||||||
|
## * *NaN* ([not a number](https://en.wikipedia.org/wiki/NaN))
|
||||||
|
##
|
||||||
|
## These values are different from ordinary numbers in that they only occur
|
||||||
|
## when a floating-point calculation encounters an error. For example:
|
||||||
|
## * Dividing a positive [F64] by `0.0` returns ∞.
|
||||||
|
## * Dividing a negative [F64] by `0.0` returns -∞.
|
||||||
|
## * Dividing a [F64] of `0.0` by `0.0` returns [*NaN*](Num.isNaN).
|
||||||
|
##
|
||||||
|
## These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
|
||||||
|
## floating point standard. Because almost all modern processors are built to
|
||||||
|
## this standard, deviating from these rules has a significant performance
|
||||||
|
## cost! Since the most common reason to choose [F64] or [F32] over [Dec] is
|
||||||
|
## access to hardware-accelerated performance, Roc follows these rules exactly.
|
||||||
|
##
|
||||||
|
## There's no literal syntax for these error values, but you can check to see if
|
||||||
|
## you ended up with one of them by using [isNaN], [isFinite], and [isInfinite].
|
||||||
|
## Whenever a function in this module could return one of these values, that
|
||||||
|
## possibility is noted in the function's documentation.
|
||||||
|
##
|
||||||
## ## Performance Notes
|
## ## Performance Notes
|
||||||
##
|
##
|
||||||
## On typical modern CPUs, performance is similar between [Dec], [F64], and [F32]
|
## On typical modern CPUs, performance is similar between [Dec], [F64], and [F32]
|
||||||
|
@ -140,7 +164,7 @@ Dec : Frac [ @Decimal128 ]
|
||||||
## an even bigger performance difference. [F32] and [F64] can do these in a
|
## an even bigger performance difference. [F32] and [F64] can do these in a
|
||||||
## single instruction, whereas [Dec] needs entire custom procedures - which use
|
## single instruction, whereas [Dec] needs entire custom procedures - which use
|
||||||
## loops and conditionals. If you need to do performance-critical trigonometry
|
## loops and conditionals. If you need to do performance-critical trigonometry
|
||||||
## or square roots, either [F32] or [F64] is probably a better choice than the
|
## or square roots, either [F64] or [F32] is probably a better choice than the
|
||||||
## usual default choice of [Dec], despite the precision problems they bring.
|
## usual default choice of [Dec], despite the precision problems they bring.
|
||||||
Frac a : Num [ @Fraction a ]
|
Frac a : Num [ @Fraction a ]
|
||||||
|
|
||||||
|
@ -524,15 +548,13 @@ isOdd : Num * -> Bool
|
||||||
## If the answer to this operation can't fit in the return value (e.g. an
|
## If the answer to this operation can't fit in the return value (e.g. an
|
||||||
## [I8] answer that's higher than 127 or lower than -128), the result is an
|
## [I8] answer that's higher than 127 or lower than -128), the result is an
|
||||||
## *overflow*. For [F64] and [F32], overflow results in an answer of either
|
## *overflow*. For [F64] and [F32], overflow results in an answer of either
|
||||||
## [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity). For
|
## ∞ or -∞. For all other number types, overflow results in a panic.
|
||||||
## all other number types, overflow results in a panic.
|
|
||||||
add : Num a, Num a -> Num a
|
add : Num a, Num a -> Num a
|
||||||
|
|
||||||
## Add two numbers and check for overflow.
|
## Add two numbers and check for overflow.
|
||||||
##
|
##
|
||||||
## This is the same as [Num.add] except if the operation overflows, instead of
|
## This is the same as [Num.add] except if the operation overflows, instead of
|
||||||
## panicking or returning [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity),
|
## panicking or returning ∞ or -∞, it will return `Err Overflow`.
|
||||||
## it will return `Err Overflow`.
|
|
||||||
addCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]*
|
addCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]*
|
||||||
|
|
||||||
## Subtract two numbers of the same type.
|
## Subtract two numbers of the same type.
|
||||||
|
@ -553,15 +575,13 @@ addCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]*
|
||||||
## If the answer to this operation can't fit in the return value (e.g. an
|
## If the answer to this operation can't fit in the return value (e.g. an
|
||||||
## [I8] answer that's higher than 127 or lower than -128), the result is an
|
## [I8] answer that's higher than 127 or lower than -128), the result is an
|
||||||
## *overflow*. For [F64] and [F32], overflow results in an answer of either
|
## *overflow*. For [F64] and [F32], overflow results in an answer of either
|
||||||
## [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity). For
|
## ∞ or -∞. For all other number types, overflow results in a panic.
|
||||||
## all other number types, overflow results in a panic.
|
|
||||||
sub : Num a, Num a -> Num a
|
sub : Num a, Num a -> Num a
|
||||||
|
|
||||||
## Subtract two numbers and check for overflow.
|
## Subtract two numbers and check for overflow.
|
||||||
##
|
##
|
||||||
## This is the same as [Num.sub] except if the operation overflows, instead of
|
## This is the same as [Num.sub] except if the operation overflows, instead of
|
||||||
## panicking or returning [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity),
|
## panicking or returning ∞ or -∞, it will return `Err Overflow`.
|
||||||
## it will return `Err Overflow`.
|
|
||||||
subCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]*
|
subCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]*
|
||||||
|
|
||||||
## Multiply two numbers of the same type.
|
## Multiply two numbers of the same type.
|
||||||
|
@ -582,15 +602,13 @@ subCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]*
|
||||||
## If the answer to this operation can't fit in the return value (e.g. an
|
## If the answer to this operation can't fit in the return value (e.g. an
|
||||||
## [I8] answer that's higher than 127 or lower than -128), the result is an
|
## [I8] answer that's higher than 127 or lower than -128), the result is an
|
||||||
## *overflow*. For [F64] and [F32], overflow results in an answer of either
|
## *overflow*. For [F64] and [F32], overflow results in an answer of either
|
||||||
## [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity). For
|
## ∞ or -∞. For all other number types, overflow results in a panic.
|
||||||
## all other number types, overflow results in a panic.
|
|
||||||
mul : Num a, Num a -> Num a
|
mul : Num a, Num a -> Num a
|
||||||
|
|
||||||
## Multiply two numbers and check for overflow.
|
## Multiply two numbers and check for overflow.
|
||||||
##
|
##
|
||||||
## This is the same as [Num.mul] except if the operation overflows, instead of
|
## This is the same as [Num.mul] except if the operation overflows, instead of
|
||||||
## panicking or returning [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity),
|
## panicking or returning ∞ or -∞, it will return `Err Overflow`.
|
||||||
## it will return `Err Overflow`.
|
|
||||||
mulCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]*
|
mulCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]*
|
||||||
|
|
||||||
## Convert
|
## Convert
|
||||||
|
@ -608,7 +626,10 @@ mulCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]*
|
||||||
##
|
##
|
||||||
## >>> Num.toStr 4.0
|
## >>> Num.toStr 4.0
|
||||||
##
|
##
|
||||||
## For other bases see #toHexStr, #toOctalStr, and #toBinaryStr.
|
## When this function is given a non-[finite](Num.isFinite)
|
||||||
|
## [F64] or [F32] value, the returned string will be `"NaN"`, `"∞"`, or `"-∞"`.
|
||||||
|
##
|
||||||
|
## To get strings in hexadecimal, octal, or binary format, use [Num.format].
|
||||||
toStr : Num * -> Str
|
toStr : Num * -> Str
|
||||||
|
|
||||||
## Convert a number into a [Str], formatted with the given options.
|
## Convert a number into a [Str], formatted with the given options.
|
||||||
|
@ -780,18 +801,6 @@ and : Int a, Int a -> Int a
|
||||||
|
|
||||||
not : Int a -> Int a
|
not : Int a -> Int a
|
||||||
|
|
||||||
## Sort ascending - that is, with the lowest first, and the highest last.
|
|
||||||
##
|
|
||||||
## List.sort Num.asc [ 3, 6, 0 ]
|
|
||||||
##
|
|
||||||
asc : Num a, Num a -> [ Eq, Lt, Gt ]
|
|
||||||
|
|
||||||
## Sort descending - that is, with the highest first, and the lowest last.
|
|
||||||
##
|
|
||||||
## List.sort Num.desc [ 3, 6, 0 ]
|
|
||||||
##
|
|
||||||
desc : Num a, Num a -> [ Eq, Lt, Gt ]
|
|
||||||
|
|
||||||
## Limits
|
## Limits
|
||||||
|
|
||||||
## The highest number that can be stored in a #Nat without overflowing its
|
## The highest number that can be stored in a #Nat without overflowing its
|
||||||
|
@ -849,39 +858,35 @@ maxU32 : U32
|
||||||
## and zero is the lowest unsigned number. Unsigned numbers cannot be negative.
|
## and zero is the lowest unsigned number. Unsigned numbers cannot be negative.
|
||||||
minU32 : U32
|
minU32 : U32
|
||||||
|
|
||||||
## The highest supported #Frac value you can have, which is approximately 1.8 × 10^308.
|
## The highest supported #F64 value you can have, which is approximately 1.8 × 10^308.
|
||||||
##
|
##
|
||||||
## If you go higher than this, your running Roc code will crash - so be careful not to!
|
## If you go higher than this, your running Roc code will crash - so be careful not to!
|
||||||
maxF64 : Frac *
|
maxF64 : F64
|
||||||
|
|
||||||
## The lowest supported #Frac value you can have, which is approximately -1.8 × 10^308.
|
## The lowest supported #F64 value you can have, which is approximately -1.8 × 10^308.
|
||||||
##
|
##
|
||||||
## If you go lower than this, your running Roc code will crash - so be careful not to!
|
## If you go lower than this, your running Roc code will crash - so be careful not to!
|
||||||
minF64 : Frac *
|
minF64 : F64
|
||||||
|
|
||||||
## The highest integer that can be represented as a #Frac without # losing precision.
|
## The highest supported #F32 value you can have, which is approximately 1.8 × 10^308.
|
||||||
## It is equal to 2^53, which is approximately 9 × 10^15.
|
|
||||||
##
|
##
|
||||||
## Some integers higher than this can be represented, but they may lose precision. For example:
|
## If you go higher than this, your running Roc code will crash - so be careful not to!
|
||||||
##
|
maxF32 : F32
|
||||||
## >>> Frac.highestInt
|
|
||||||
##
|
|
||||||
## >>> Frac.highestInt + 100 # Increasing may lose precision
|
|
||||||
##
|
|
||||||
## >>> Frac.highestInt - 100 # Decreasing is fine - but watch out for lowestLosslessInt!
|
|
||||||
maxPreciseInt : Frac *
|
|
||||||
|
|
||||||
## The lowest integer that can be represented as a #Frac without losing precision.
|
## The lowest supported #F32 value you can have, which is approximately -1.8 × 10^308.
|
||||||
## It is equal to -2^53, which is approximately -9 × 10^15.
|
|
||||||
##
|
##
|
||||||
## Some integers lower than this can be represented, but they may lose precision. For example:
|
## If you go lower than this, your running Roc code will crash - so be careful not to!
|
||||||
|
minF32 : F32
|
||||||
|
|
||||||
|
## The highest supported #F64 value you can have, which is approximately 1.8 × 10^308.
|
||||||
##
|
##
|
||||||
## >>> Frac.lowestIntVal
|
## If you go higher than this, your running Roc code will crash - so be careful not to!
|
||||||
|
maxDec : Dec
|
||||||
|
|
||||||
|
## The lowest supported #F64 value you can have, which is approximately -1.8 × 10^308.
|
||||||
##
|
##
|
||||||
## >>> Frac.lowestIntVal - 100 # Decreasing may lose precision
|
## If you go lower than this, your running Roc code will crash - so be careful not to!
|
||||||
##
|
maxDec : Dec
|
||||||
## >>> Frac.lowestIntVal + 100 # Increasing is fine - but watch out for highestInt!
|
|
||||||
maxPreciseInt : Frac *
|
|
||||||
|
|
||||||
## Constants
|
## Constants
|
||||||
|
|
||||||
|
@ -916,14 +921,14 @@ atan : Frac a -> Frac a
|
||||||
## Calling [div] on a [Dec] denominator of zero will cause a panic.
|
## Calling [div] on a [Dec] denominator of zero will cause a panic.
|
||||||
##
|
##
|
||||||
## Calling [div] on [F32] and [F64] values follows these rules:
|
## Calling [div] on [F32] and [F64] values follows these rules:
|
||||||
## * Dividing a positive [F32] or [F64] by zero returns [Infinity](#isPositiveInfinity).
|
## * Dividing a positive [F64] or [F32] by zero returns ∞.
|
||||||
## * Dividing a negative [F32] or [F64] by zero returns [-Infinity](#isNegativeInfinity).
|
## * Dividing a negative [F64] or [F32] by zero returns -∞.
|
||||||
## * Dividing a zero [F32] or [F64] by zero returns [NaN](#isNaN).
|
## * Dividing a zero [F64] or [F32] by zero returns [*NaN*](Num.isNaN).
|
||||||
##
|
##
|
||||||
## > These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
|
## > These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
|
||||||
## > floating point standard. Since almost all modern processors are built to
|
## > floating point standard. Because almost all modern processors are built to
|
||||||
## > this standard, deviating from these rules has a significant performance
|
## > this standard, deviating from these rules has a significant performance
|
||||||
## > cost. Since the most common reason to choose [F32] or [F64] over [Dec] is
|
## > cost! Since the most common reason to choose [F64] or [F32] over [Dec] is
|
||||||
## > access to hardware-accelerated performance, Roc follows these rules exactly.
|
## > access to hardware-accelerated performance, Roc follows these rules exactly.
|
||||||
##
|
##
|
||||||
## To divide an [Int] and a [Frac], first convert the [Int] to a [Frac] using
|
## To divide an [Int] and a [Frac], first convert the [Int] to a [Frac] using
|
||||||
|
@ -952,7 +957,7 @@ div : Frac a, Frac a -> Frac a
|
||||||
##
|
##
|
||||||
## Passing [mod] a [Dec] value of zero for its second argument will cause a panic.
|
## Passing [mod] a [Dec] value of zero for its second argument will cause a panic.
|
||||||
## Passing [mod] a [F32] and [F64] value for its second argument will cause it
|
## Passing [mod] a [F32] and [F64] value for its second argument will cause it
|
||||||
## to return [NaN](#isNaN).
|
## to return [*NaN*](Num.isNaN).
|
||||||
##
|
##
|
||||||
## >>> 5.0 % 7.0
|
## >>> 5.0 % 7.0
|
||||||
##
|
##
|
||||||
|
@ -999,14 +1004,14 @@ expBySquaring : Int a, U8 -> Int a
|
||||||
## function a negative number! Calling [sqrt] on a negative [Dec] will cause a panic.
|
## function a negative number! Calling [sqrt] on a negative [Dec] will cause a panic.
|
||||||
##
|
##
|
||||||
## Calling [sqrt] on [F32] and [F64] values follows these rules:
|
## Calling [sqrt] on [F32] and [F64] values follows these rules:
|
||||||
## * Passing a negative [F32] or [F64] returns [NaN](#isNaN).
|
## * Passing a negative [F64] or [F32] returns [*NaN*](Num.isNaN).
|
||||||
## * Passing [NaN](#isNaN) or [-Infinity](isNegativeInfinity) also returns [NaN](#isNaN).
|
## * Passing [*NaN*](Num.isNaN) or -∞ also returns [*NaN*](Num.isNaN).
|
||||||
## * Passing [Infinity](isPositiveInfinity) returns [Infinity].
|
## * Passing ∞ returns ∞.
|
||||||
##
|
##
|
||||||
## > These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
|
## > These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
|
||||||
## > floating point standard. Since almost all modern processors are built to
|
## > floating point standard. Because almost all modern processors are built to
|
||||||
## > this standard, deviating from these rules has a significant performance
|
## > this standard, deviating from these rules has a significant performance
|
||||||
## > cost. Since the most common reason to choose [F32] or [F64] over [Dec] is
|
## > cost! Since the most common reason to choose [F64] or [F32] over [Dec] is
|
||||||
## > access to hardware-accelerated performance, Roc follows these rules exactly.
|
## > access to hardware-accelerated performance, Roc follows these rules exactly.
|
||||||
##
|
##
|
||||||
## >>> Frac.sqrt 4.0
|
## >>> Frac.sqrt 4.0
|
||||||
|
@ -1020,51 +1025,148 @@ expBySquaring : Int a, U8 -> Int a
|
||||||
## >>> Frac.sqrt -4.0dec
|
## >>> Frac.sqrt -4.0dec
|
||||||
sqrt : Frac a -> Frac a
|
sqrt : Frac a -> Frac a
|
||||||
|
|
||||||
|
## Bit shifts
|
||||||
|
|
||||||
|
## [Logical bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift) left.
|
||||||
|
##
|
||||||
|
## `a << b` is shorthand for `Num.shl a b`.
|
||||||
|
shl : Int a, Int a -> Int a
|
||||||
|
|
||||||
|
## [Arithmetic bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift) left.
|
||||||
|
##
|
||||||
|
## This is called `shlWrap` because any bits shifted
|
||||||
|
## off the beginning of the number will be wrapped around to
|
||||||
|
## the end. (In contrast, [shl] replaces discarded bits with zeroes.)
|
||||||
|
shlWrap : Int a, Int a -> Int a
|
||||||
|
|
||||||
|
## [Logical bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift) right.
|
||||||
|
##
|
||||||
|
## `a >> b` is shorthand for `Num.shr a b`.
|
||||||
|
shr : Int a, Int a -> Int a
|
||||||
|
|
||||||
|
## [Arithmetic bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift) right.
|
||||||
|
##
|
||||||
|
## This is called `shlWrap` because any bits shifted
|
||||||
|
## off the end of the number will be wrapped around to
|
||||||
|
## the beginning. (In contrast, [shr] replaces discarded bits with zeroes.)
|
||||||
|
shrWrap : Int a, Int a -> Int a
|
||||||
|
|
||||||
|
|
||||||
## [Endianness](https://en.wikipedia.org/wiki/Endianness)
|
## [Endianness](https://en.wikipedia.org/wiki/Endianness)
|
||||||
Endi : [ Big, Little ]
|
Endi : [ Big, Little ]
|
||||||
|
|
||||||
toBytes : Num *, Endi -> List U8
|
toBytes : Num *, Endi -> List U8
|
||||||
|
|
||||||
|
|
||||||
|
## Comparison
|
||||||
|
|
||||||
|
## Returns `True` if the first number is less than the second.
|
||||||
|
##
|
||||||
|
## `a < b` is shorthand for `Num.isLt a b`.
|
||||||
|
##
|
||||||
|
## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN*
|
||||||
|
## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
|
||||||
|
##
|
||||||
|
## >>> 5
|
||||||
|
## >>> |> Num.isLt 6
|
||||||
|
isLt : Num a, Num a -> Bool
|
||||||
|
|
||||||
|
## Returns `True` if the first number is less than or equal to the second.
|
||||||
|
##
|
||||||
|
## `a <= b` is shorthand for `Num.isLte a b`.
|
||||||
|
##
|
||||||
|
## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN*
|
||||||
|
## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
|
||||||
|
isLte : Num a, Num a -> Bool
|
||||||
|
|
||||||
|
## Returns `True` if the first number is greater than the second.
|
||||||
|
##
|
||||||
|
## `a > b` is shorthand for `Num.isGt a b`.
|
||||||
|
##
|
||||||
|
## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN*
|
||||||
|
## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
|
||||||
|
##
|
||||||
|
## >>> 6
|
||||||
|
## >>> |> Num.isGt 5
|
||||||
|
isGt : Num a, Num a -> Bool
|
||||||
|
|
||||||
|
## Returns `True` if the first number is greater than or equal to the second.
|
||||||
|
##
|
||||||
|
## `a >= b` is shorthand for `Num.isGte a b`.
|
||||||
|
##
|
||||||
|
## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN*
|
||||||
|
## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
|
||||||
|
isGte : Num a, Num a -> Bool
|
||||||
|
|
||||||
|
## Returns the higher of two numbers.
|
||||||
|
##
|
||||||
|
## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN*
|
||||||
|
## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
|
||||||
|
higher : Num a, Num a -> Num a
|
||||||
|
|
||||||
|
## Returns the lower of two numbers.
|
||||||
|
##
|
||||||
|
## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN*
|
||||||
|
## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
|
||||||
|
lower : Num a, Num a -> Num a
|
||||||
|
|
||||||
|
# Branchless implementation that works for all numeric types:
|
||||||
|
#
|
||||||
|
# let is_lt = arg1 < arg2;
|
||||||
|
# let is_eq = arg1 == arg2;
|
||||||
|
# return (is_lt as i8 - is_eq as i8) + 1;
|
||||||
|
#
|
||||||
|
# 1, 1 -> (0 - 1) + 1 == 0 # Eq
|
||||||
|
# 5, 1 -> (0 - 0) + 1 == 1 # Gt
|
||||||
|
# 1, 5 -> (1 - 0) + 1 == 2 # Lt
|
||||||
|
|
||||||
|
## Returns `Lt` if the first number is less than the second, `Gt` if
|
||||||
|
## the first is greater than the second, and `Eq` if they're equal.
|
||||||
|
##
|
||||||
|
## Although this can be passed to [List.sort], you'll get better performance
|
||||||
|
## by using [List.sortAsc] or [List.sortDesc] instead.
|
||||||
|
compare : Num a, Num a -> [ Lt, Eq, Gt ]
|
||||||
|
|
||||||
|
## Special Floating-Point Values
|
||||||
|
|
||||||
## When given a [F64] or [F32] value, returns `False` if that value is
|
## When given a [F64] or [F32] value, returns `False` if that value is
|
||||||
## [*NaN*](https://en.wikipedia.org/wiki/NaN). (Returns `False` if that value is *Infinity* or *-Infinity*.)
|
## [*NaN*](Num.isNaN), ∞ or -∞, and `True` otherwise.
|
||||||
|
##
|
||||||
|
## Always returns `True` when given a [Dec].
|
||||||
|
##
|
||||||
|
## This is the opposite of [isInfinite], except when given [*NaN*](Num.isNaN). Both
|
||||||
|
## [isFinite] and [isInfinite] return `False` for [*NaN*](Num.isNaN).
|
||||||
|
isFinite : Frac * -> Bool
|
||||||
|
|
||||||
|
## When given a [F64] or [F32] value, returns `True` if that value is either
|
||||||
|
## ∞ or -∞, and `False` otherwise.
|
||||||
|
##
|
||||||
|
## Always returns `False` when given a [Dec].
|
||||||
|
##
|
||||||
|
## This is the opposite of [isFinite], except when given [*NaN*](Num.isNaN). Both
|
||||||
|
## [isFinite] and [isInfinite] return `False` for [*NaN*](Num.isNaN).
|
||||||
|
isInfinite : Frac * -> Bool
|
||||||
|
|
||||||
|
## When given a [F64] or [F32] value, returns `True` if that value is
|
||||||
|
## *NaN* ([not a number](https://en.wikipedia.org/wiki/NaN)), and `False` otherwise.
|
||||||
##
|
##
|
||||||
## Always returns `False` when given a [Dec].
|
## Always returns `False` when given a [Dec].
|
||||||
##
|
##
|
||||||
## >>> Num.isNaN 12.3
|
## >>> Num.isNaN 12.3
|
||||||
##
|
##
|
||||||
## >>> Num.isNaN (Num.sqrtOrNaN -2)
|
## >>> Num.isNaN (Num.sqrt -2)
|
||||||
##
|
##
|
||||||
## See also [isFinite].
|
## *NaN* is unusual from other numberic values in that:
|
||||||
|
## * *NaN* is not equal to any other number, even itself. [Bool.isEq] always returns `False` if either argument is *NaN*.
|
||||||
|
## * *NaN* has no ordering, so [isLt], [isLte], [isGt], and [isGte] always return `False` if either argument is *NaN*.
|
||||||
|
##
|
||||||
|
## These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
|
||||||
|
## floating point standard. Because almost all modern processors are built to
|
||||||
|
## this standard, deviating from these rules has a significant performance
|
||||||
|
## cost! Since the most common reason to choose [F64] or [F32] over [Dec] is
|
||||||
|
## access to hardware-accelerated performance, Roc follows these rules exactly.
|
||||||
|
##
|
||||||
|
## Note that you should never put a *NaN* into a [Set], or use it as the key in
|
||||||
|
## a [Dict]. The result is entries that can never be removed from those
|
||||||
|
## collections! See the documentation for [Set.add] and [Dict.insert] for details.
|
||||||
isNaN : Frac * -> Bool
|
isNaN : Frac * -> Bool
|
||||||
|
|
||||||
## When given a [F64] or [F32] value, returns `False` if that value is
|
|
||||||
## [*NaN*](https://en.wikipedia.org/wiki/NaN), *Infinity*, or *-Infinity*.
|
|
||||||
##
|
|
||||||
## Always returns `True` when given a [Dec].
|
|
||||||
##
|
|
||||||
## See also [isInfinite].
|
|
||||||
isFinite : Frac * -> Bool
|
|
||||||
|
|
||||||
## When given a [F64] or [F32] value, returns `True` if that value is either
|
|
||||||
## *Infinity* or *-Infinity*. (Returns `False` if that value is [*NaN*](https://en.wikipedia.org/wiki/NaN).)
|
|
||||||
##
|
|
||||||
## Always returns `False` when given a [Dec].
|
|
||||||
##
|
|
||||||
## See also [isFinite], [isPositiveInfinity], and [isNegativeInfinity].
|
|
||||||
isInfinite : Frac * -> Bool
|
|
||||||
|
|
||||||
## When given a [F64] or [F32] value, returns `True` if that value is
|
|
||||||
## *Infinity*. (Returns `False` if that value is *-Infinity* or [*NaN*](https://en.wikipedia.org/wiki/NaN).)
|
|
||||||
##
|
|
||||||
## Always returns `False` when given a [Dec].
|
|
||||||
##
|
|
||||||
## See also [isNegativeInfinity], [isInfinite], and [isFinite].
|
|
||||||
isPositiveInfinity : Frac * -> Bool
|
|
||||||
|
|
||||||
## When given a [F64] or [F32] value, returns `True` if that value is
|
|
||||||
## *Infinity*. (Returns `False` if that value is *-Infinity* or [*NaN*](https://en.wikipedia.org/wiki/NaN).)
|
|
||||||
##
|
|
||||||
## Always returns `False` when given a [Dec].
|
|
||||||
##
|
|
||||||
## See also [isPositiveInfinity], [isInfinite], and [isFinite].
|
|
||||||
isNegativeInfinity : Frac * -> Bool
|
|
||||||
|
|
|
@ -18,7 +18,9 @@ len : Set * -> Nat
|
||||||
|
|
||||||
# TODO: removed `'` from signature because parser does not support it yet
|
# TODO: removed `'` from signature because parser does not support it yet
|
||||||
# Original signature: `add : Set 'elem, 'elem -> Set 'elem`
|
# Original signature: `add : Set 'elem, 'elem -> Set 'elem`
|
||||||
## Since NaN is defined to be unequal to NaN, panics if given NaN.
|
## Make sure never to add a *NaN* to a [Set]! Becuase *NaN* is defined to be
|
||||||
|
## unequal to *NaN*, adding a *NaN* results in an entry that can never be
|
||||||
|
## retrieved or removed from the [Set].
|
||||||
add : Set elem, elem -> Set elem
|
add : Set elem, elem -> Set elem
|
||||||
|
|
||||||
## Drops the given element from the set.
|
## Drops the given element from the set.
|
||||||
|
|
|
@ -456,10 +456,17 @@ parseU64 : Str, NumParseConfig -> Result { val : U64, rest : Str } [ Expected [
|
||||||
parseI64 : Str, NumParseConfig -> Result { val : I64, rest : Str } [ Expected [ NumI64 ]* Str ]*
|
parseI64 : Str, NumParseConfig -> Result { val : I64, rest : Str } [ Expected [ NumI64 ]* Str ]*
|
||||||
parseU128 : Str, NumParseConfig -> Result { val : U128, rest : Str } [ Expected [ NumU128 ]* Str ]*
|
parseU128 : Str, NumParseConfig -> Result { val : U128, rest : Str } [ Expected [ NumU128 ]* Str ]*
|
||||||
parseI128 : Str, NumParseConfig -> Result { val : I128, rest : Str } [ Expected [ NumI128 ]* Str ]*
|
parseI128 : Str, NumParseConfig -> Result { val : I128, rest : Str } [ Expected [ NumI128 ]* Str ]*
|
||||||
parseF64 : Str, NumParseConfig -> Result { val : U128, rest : Str } [ Expected [ NumF64 ]* Str ]*
|
|
||||||
parseF32 : Str, NumParseConfig -> Result { val : I128, rest : Str } [ Expected [ NumF32 ]* Str ]*
|
|
||||||
parseDec : Str, NumParseConfig -> Result { val : Dec, rest : Str } [ Expected [ NumDec ]* Str ]*
|
parseDec : Str, NumParseConfig -> Result { val : Dec, rest : Str } [ Expected [ NumDec ]* Str ]*
|
||||||
|
|
||||||
|
## If the string begins with a [finite](Num.isFinite) [F64] number, return
|
||||||
|
## that number along with the rest of the string after it.
|
||||||
|
##
|
||||||
|
## If the string begins with `"NaN"`, `"∞"`, and `"-∞"` (which do not represent
|
||||||
|
## [finite](Num.isFinite) numbers), they will be similarly accepted and
|
||||||
|
## translated into their respective [F64] values.
|
||||||
|
parseF64 : Str, NumParseConfig -> Result { val : F64, rest : Str } [ Expected [ NumF64 ]* Str ]*
|
||||||
|
parseF32 : Str, NumParseConfig -> Result { val : F32, rest : Str } [ Expected [ NumF32 ]* Str ]*
|
||||||
|
|
||||||
## Notes:
|
## Notes:
|
||||||
## * You can allow a decimal mark for integers; they'll only parse if the numbers after it are all 0.
|
## * You can allow a decimal mark for integers; they'll only parse if the numbers after it are all 0.
|
||||||
## * For `wholeSep`, `Required` has a payload for how many digits (e.g. "required every 3 digits")
|
## * For `wholeSep`, `Required` has a payload for how many digits (e.g. "required every 3 digits")
|
||||||
|
|
|
@ -42,6 +42,23 @@ pub const NODE_BYTES: usize = 32;
|
||||||
// usize pointers, which would be too big for us to have 16B nodes.
|
// usize pointers, which would be too big for us to have 16B nodes.
|
||||||
// On the plus side, we could be okay with higher memory usage early on,
|
// On the plus side, we could be okay with higher memory usage early on,
|
||||||
// and then later use the Mesh strategy to reduce long-running memory usage.
|
// and then later use the Mesh strategy to reduce long-running memory usage.
|
||||||
|
//
|
||||||
|
// With this system, we can allocate up to 4B nodes. If we wanted to keep
|
||||||
|
// a generational index in there, like https://crates.io/crates/sharded-slab
|
||||||
|
// does, we could use some of the 32 bits for that. For example, if we wanted
|
||||||
|
// to have a 5-bit generational index (supporting up to 32 generations), then
|
||||||
|
// we would have 27 bits remaining, meaning we could only support at most
|
||||||
|
// 134M nodes. Since the editor has a separate Pool for each module, is that
|
||||||
|
// enough for any single module we'll encounter in practice? Probably, and
|
||||||
|
// especially if we allocate super large collection literals on the heap instead
|
||||||
|
// of in the pool.
|
||||||
|
//
|
||||||
|
// Another possible design is to try to catch reuse bugs using an "ASan" like
|
||||||
|
// approach: in development builds, whenever we "free" a particular slot, we
|
||||||
|
// can add it to a dev-build-only "freed nodes" list and don't hand it back
|
||||||
|
// out (so, we leak the memory.) Then we can (again, in development builds only)
|
||||||
|
// check to see if we're about to store something in zeroed-out memory; if so, check
|
||||||
|
// to see if it was
|
||||||
|
|
||||||
#[derive(Debug, Eq)]
|
#[derive(Debug, Eq)]
|
||||||
pub struct NodeId<T> {
|
pub struct NodeId<T> {
|
||||||
|
|
|
@ -1427,6 +1427,8 @@ Here are various Roc expressions involving operators, and what they desugar to.
|
||||||
| `a ^ b` | `Num.pow a b` |
|
| `a ^ b` | `Num.pow a b` |
|
||||||
| `a % b` | `Num.rem a b` |
|
| `a % b` | `Num.rem a b` |
|
||||||
| `a %% b` | `Num.mod a b` |
|
| `a %% b` | `Num.mod a b` |
|
||||||
|
| `a >> b` | `Num.shr a b` |
|
||||||
|
| `a << b` | `Num.shl a b` |
|
||||||
| `-a` | `Num.neg a` |
|
| `-a` | `Num.neg a` |
|
||||||
| `-f x y` | `Num.neg (f x y)` |
|
| `-f x y` | `Num.neg (f x y)` |
|
||||||
| `a == b` | `Bool.isEq a b` |
|
| `a == b` | `Bool.isEq a b` |
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue