Skip to content

Commit ea1e00a

Browse files
committed
Update numeric literals documentation
1 parent af43f16 commit ea1e00a

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

docs/docs/reference/changed-features/numeric-literals.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ val y: BigInt = 0x123_abc_789_def_345_678_901
4545
val z: BigDecimal = 111222333444.55
4646
```
4747
are legal by rule (2), since both `BigInt` and `BigDecimal` have `FromDigits` instances
48-
(which implement the `FromDigits` subclasses `FromDigits.WithRadix` and `FromDigits.Decimal`, respectively).
48+
(which implement the `FromDigits` subclasses `FromDigits.WithRadix` and `FromDigits.Floating`, respectively).
4949
On the other hand,
5050
```scala
5151
val x = -10_000_000_000
@@ -112,6 +112,34 @@ class NumberTooSmall (msg: String = "number too small") extends FromDigi
112112
class MalformedNumber(msg: String = "malformed number literal") extends FromDigitsException(msg)
113113
```
114114

115+
### Compiler Expansion
116+
117+
The companion object `FromDigits` also defines four methods that may be used to provide a given instance of one of the subclasses of `FromDigits`:
118+
```scala
119+
inline def fromDigits[T](given x: FromDigits[T]): x.type = x
120+
121+
inline def fromRadixDigits[T](given x: FromDigits.WithRadix[T]): x.type = x
122+
123+
inline def fromDecimalDigits[T](given x: FromDigits.Decimal[T]): x.type = x
124+
125+
inline def fromFloatingDigits[T](given x: FromDigits.Floating[T]): x.type = x
126+
```
127+
128+
If a numeric literal has a known expected type `T` that is not one of the primitive numeric types, then the compiler will search for a given instance of `FromDigits[T]`. If one exists, then the compiler expands the literal to a call on the `fromDigits` method on the result obtained from calling one of the above four methods. Example:
129+
```scala
130+
0xCAFEBABE: BigDecimal
131+
```
132+
Because the `FromDigits` companion object defines a given `FromDigits.Floating[BigDecimal]`, then there exists a given `FromDigits[BigDecimal]`. Therefore the expression above would expand to the following, given that the digits form a hex literal:
133+
```scala
134+
FromDigits.fromRadixDigits[BigDecimal].fromDigits("0CAFEBABE", 16)
135+
```
136+
Because the given clause of `fromRadixDigits` in the call above expects a given instance of type `FromDigits.WithRadix[BigDecimal]`, and the scala library does not define one, the following error is issued:
137+
```scala
138+
1 |0xCAFEBABE: BigDecimal
139+
|^
140+
|Type BigDecimal does not have a FromDigits instance for whole numbers with radix other than 10.
141+
```
142+
115143
### Example
116144

117145
As a fully worked out example, here is an implementation of a new numeric class, `BigFloat`, that accepts numeric literals. `BigFloat` is defined in terms of a `BigInt` mantissa and an `Int` exponent:
@@ -174,7 +202,7 @@ With the setup of the previous section, a literal like
174202
```
175203
would be expanded by the compiler to
176204
```scala
177-
BigFloat.FromDigits.fromDigits("1e100000000000")
205+
FromDigits.fromFloatingDigits[BigFloat].fromDigits("1e100000000000")
178206
```
179207
Evaluating this expression throws a `NumberTooLarge` exception at run time. We would like it to
180208
produce a compile-time error instead. We can achieve this by tweaking the `BigFloat` class

0 commit comments

Comments
 (0)