Repository F# setup
open Reified
open Reified.Refinements
open Reified.Result

Numbers

Data.Number stores a number as text so conversion does not discard precision or exponent notation. Human-readable and JSON rendering both write that token without quotes.

Verified
open Reified
open Reified.DataDSL
Requires & types
Requires: (packages: Reified.Data)

Integers

int and int64 use ordinary base-10 digits with an optional leading minus sign.

Verified
let intValue = data [ "count" => 5000; "change" => -12L ]

Data.render intValue
// => "{ count: 5000, change: -12 }"
Requires & types
Requires: open Reified; open Reified.DataDSL (packages: Reified.Data)
val intValue: Data

Decimals

decimal uses . as the decimal separator regardless of the machine's locale. The conversion retains the scale that the decimal value carries, including trailing zeros.

Verified
let decimalValue = data [ "price" => 19.9500m ]

Data.render decimalValue
// => "{ price: 19.9500 }"
Requires & types
Requires: open Reified; open Reified.DataDSL (packages: Reified.Data)
val decimalValue: Data

Floating-point values

float uses a round-trip token: it writes enough digits for parsing the token to recover the same finite floating-point value. NaN, positive infinity, and negative infinity are rejected because JSON cannot represent them.

Verified
let floatValue = data [ "ratio" => 0.1 ]

Data.render floatValue
// => "{ ratio: 0.1 }"
Requires & types
Requires: open Reified; open Reified.DataDSL (packages: Reified.Data)
val floatValue: Data

Exact tokens with num

Use num when the spelling is part of the value you need to retain. It accepts one valid JSON number and keeps the token unchanged.

Verified
let numValue = data [ "measurement" => num "1.2300e+4" ]

Data.render numValue
// => "{ measurement: 1.2300e+4 }"
Requires & types
Requires: open Reified; open Reified.DataDSL (packages: Reified.Data)
val numValue: Data

The same JSON-number grammar is checked on .NET and Fable. Invalid tokens such as "01", "NaN", "Infinity", leading + signs, surrounding whitespace, and incomplete fractions or exponents raise ArgumentException.

Exact comparison

Exact comparison compares number tokens, not their mathematical values.

Verified
Data.compare (num "1") (num "1.0")
// => Error [
//      { Path = DataPath.empty
//        Expected = Some (Data.Number "1")
//        Actual = Some (Data.Number "1.0")
//        Cause = DataDifferenceCause.DifferentValue }
//    ]
Requires & types
Requires: open Reified; open Reified.DataDSL (packages: Reified.Data)

Use anyNumber or a predicate when a match should accept several numeric spellings.