|
2 | 2 |
|
3 | 3 | Or, "what is the PureScript equivalent of \<X operator\> in JS?"
|
4 | 4 |
|
5 |
| -Although the PureScript language defines no built-in operators, plenty |
6 |
| -are defined in the `Prelude` and other core libraries. This guide |
7 |
| -gives you a overview of these operators and the corresponding |
8 |
| -operators in JavaScript. |
| 5 | +Although the PureScript language defines no built-in operators, plenty are defined in the `Prelude` and other core libraries. This guide gives you a overview of these operators and the corresponding operators in JavaScript. |
9 | 6 |
|
10 | 7 | ## JavaScript's unary operators
|
11 | 8 |
|
12 |
| -All PureScript operators are binary, with one exception: there is |
13 |
| -syntax sugar for unary negation, whereby in PureScript code, `-x` is |
14 |
| -desugared to `negate x`, which uses whichever `negate` is in scope. |
| 9 | +All PureScript operators are binary, with one exception: there is syntax sugar for unary negation, whereby in PureScript code, `-x` is desugared to `negate x`, which uses whichever `negate` is in scope. |
15 | 10 |
|
16 |
| -This means that the PureScript analogues to unary JavaScript operators |
17 |
| -(other than `-`) are not operators, but normal functions which must be |
18 |
| -applied using the standard prefix-style function application, so |
19 |
| -e.g. `!x` in JS must be written as `not x` in PureScript. |
| 11 | +This means that the PureScript analogues to unary JavaScript operators (other than `-`) are not operators, but normal functions which must be applied using the standard prefix-style function application, so e.g. `!x` in JS must be written as `not x` in PureScript. |
20 | 12 |
|
21 | 13 | | JS Operator | PureScript Function | Defined in | Meaning |
|
22 | 14 | |-------------|---------------------|-----------------------|------------------|
|
@@ -50,46 +42,18 @@ e.g. `!x` in JS must be written as `not x` in PureScript.
|
50 | 42 | | `>>` | `shr` | `Data.Int.Bits` | Shift Right |
|
51 | 43 | | `>>>` | `zshr` | `Data.Int.Bits` | Zero-fill Shift Right |
|
52 | 44 |
|
53 |
| -Most of these functions and operators are re-exported by the |
54 |
| -`Prelude`, so to have access to them in your code, you should normally |
55 |
| -just write `import Prelude`. |
| 45 | +Most of these functions and operators are re-exported by the `Prelude`, so to have access to them in your code, you should normally just write `import Prelude`. |
56 | 46 |
|
57 |
| -Additionally, many of these functions and operators are defined in |
58 |
| -type classes and work with lots of different types. For example, `+` |
59 |
| -and `*` work with not only `Int` and `Number`, but also any instance |
60 |
| -of the `Semiring` type class defined in the `Prelude`. |
| 47 | +Additionally, many of these functions and operators are defined in type classes and work with lots of different types. For example, `+` and `*` work with not only `Int` and `Number`, but also any instance of the `Semiring` type class defined in the `Prelude`. |
61 | 48 |
|
62 | 49 | ### A note on remainder/modulus (`%`)
|
63 | 50 |
|
64 |
| -Normally, when we ask for the remainder of one number after dividing |
65 |
| -by another, we are talking about integers. Clearly the remainder of 10 |
66 |
| -after dividing by 3 is 1, and indeed in JS, `10 % 3 == 1`. Likewise, |
67 |
| -in PureScript, ``10 `mod` 3 == 1``. |
68 |
| - |
69 |
| -It's a bit harder to say what a 'remainder' operation should mean if |
70 |
| -we are trying to extend it to real (non-integral) numbers, |
71 |
| -though. Real numbers can be divided into one another with nothing |
72 |
| -'left over', i.e. in some sense, the remainder of dividing one number |
73 |
| -by another is always 0. |
74 |
| - |
75 |
| -Since JS just has one number type, it has to come up with a sensible |
76 |
| -way of handling cases where one or both of its arguments are |
77 |
| -non-integral. To address this, it uses a behaviour where it tries to |
78 |
| -find the largest *integer* multiple of the second argument which is |
79 |
| -smaller than the first argument, and then returns the difference |
80 |
| -between these. For example, in JS, `10.5 % 3 == 1.5`. |
81 |
| - |
82 |
| -If this is the behaviour you want in PureScript, you should use `%` |
83 |
| -from the `Math` module in `purescript-math`. Its type is `Number -> |
84 |
| -Number -> Number` and it simply delegates to the `%` operator in JS. |
85 |
| - |
86 |
| -However, PureScript's `Prelude` aims to provide a stronger theoretical |
87 |
| -foundation for common operators such as this one, which is why the |
88 |
| -`Prelude` exports a slightly different function, `mod :: forall |
89 |
| -a. EuclideanRing a => a -> a -> a`. For integers, `mod` works how you |
90 |
| -expect it to: ``10 `mod` 3 == 1``, just as before. However, for |
91 |
| -Numbers, `mod` always returns 0. This may be surprising; however, the |
92 |
| -reason it works this way is that it is based upon a mathematical |
93 |
| -structure called a *Euclidean Ring*, whose definition requires this |
94 |
| -behaviour. For more info, see the [EuclideanRing |
95 |
| -documentation](https://pursuit.purescript.org/packages/purescript-prelude/2.1.0/docs/Data.EuclideanRing#t:EuclideanRing). |
| 51 | +Normally, when we ask for the remainder of one number after dividing by another, we are talking about integers. Clearly the remainder of 10 after dividing by 3 is 1, and indeed in JS, `10 % 3 == 1`. Likewise, in PureScript, ``10 `mod` 3 == 1``. |
| 52 | + |
| 53 | +It's a bit harder to say what a 'remainder' operation should mean if we are trying to extend it to real (non-integral) numbers, though. Real numbers can be divided into one another with nothing 'left over', i.e. in some sense, the remainder of dividing one number by another is always 0. |
| 54 | + |
| 55 | +Since JS just has one number type, it has to come up with a sensible way of handling cases where one or both of its arguments are non-integral. To address this, it uses a behaviour where it tries to find the largest *integer* multiple of the second argument which is smaller than the first argument, and then returns the difference between these. For example, in JS, `10.5 % 3 == 1.5`. |
| 56 | + |
| 57 | +If this is the behaviour you want in PureScript, you should use `%` from the `Math` module in `purescript-math`. Its type is `Number -> Number -> Number` and it simply delegates to the `%` operator in JS. |
| 58 | + |
| 59 | +However, PureScript's `Prelude` aims to provide a stronger theoretical foundation for common operators such as this one, which is why the `Prelude` exports a slightly different function, `mod :: forall a. EuclideanRing a => a -> a -> a`. For integers, `mod` works how you expect it to: ``10 `mod` 3 == 1``, just as before. However, for Numbers, `mod` always returns 0. This may be surprising; however, the reason it works this way is that it is based upon a mathematical structure called a *Euclidean Ring*, whose definition requires this behaviour. For more info, see the [EuclideanRing documentation](https://pursuit.purescript.org/packages/purescript-prelude/2.1.0/docs/Data.EuclideanRing#t:EuclideanRing). |
0 commit comments