Repository F# setup
open Reified
open Reified.Refinements
open Reified.Result
open Reified.Schema.JsonWhat Data represents
Data represents structured values with six cases. The model maps directly to JSON and also works for fixtures,
configuration, command-line input, form values, events, and other tree-shaped data.
type Data =
| Null
| Text of string
| Number of token: string
| Bool of bool
| List of Data list
| Object of (string * Data) list
07-data_15-what-it-does.md_page.DataNullTextstringAn abbreviation for the CLI type . Basic Types
Numbertoken: stringBoolboolAn abbreviation for the CLI type . Basic Types
ListlistThe type of immutable singly-linked lists. See the module for further operations related to lists. Use the constructors [] and :: (infix) to create values of this type, or the notation [1; 2; 3]. Use the values in the List module to manipulate values of this type, or pattern match against the values directly. See also F# Language Guide - Lists.
ObjectData.Null
Null is a present value with no scalar content. In JSON it renders as null.
Data.render Data.Null
// => "null"A null field is different from an absent field. In literal syntax, "value" => nil includes a null field, while
"value" ?=> None omits the field.
Data.Text
Text stores a .NET string and renders it as a JSON string with the required escaping.
Data.render (Data.Text "Ada\nLovelace")
// => "\"Ada\\nLovelace\""A null .NET string converts to Data.Null; it does not become Data.Text null.
Data.Number
Number stores the number as a token rather than converting every number to one CLR numeric type. This retains
large integers, decimal precision, trailing zeros, and exponent notation.
Data.Number "1.2300e+4"
07-data_15-what-it-does.md_page.DataNumberThe token is visible to exact comparison: 1, 1.0, and 1e0 are different. Use the num function rather than the
union case when accepting text, because num checks that the token is a valid JSON number.
See Numbers for conversion rules and examples.
Data.Bool
Bool stores true or false and renders it without quotes.
Data.render (Data.Bool true)
// => "true"Data.List
List stores ordered Data values. Order and repeated values are preserved.
Data.render (Data.List [ Data.Text "author"; Data.Text "admin" ])
// => "[\"author\", \"admin\"]"Exact comparison checks every item and its position. Matching can instead check an ordered subsequence, an unordered subset, every item, or at least one item.
Data.Object
Object stores an ordered list of name/value pairs. It preserves declaration order and duplicate field names.
let value =
Data.Object [
"name", Data.Text "Ada"
"name", Data.Text "Grace"
]
Data.render value
// => "{ name: \"Ada\", name: \"Grace\" }"Path lookup and edits select the last field when a name is repeated. Exact comparison observes every field, including duplicates and order. Partial object matching consumes matching duplicate fields one occurrence at a time.
Paths
DataPath identifies nested fields and zero-based list indexes. String paths use dots for ordinary field names,
brackets for indexes, and quoted brackets for names containing punctuation.
DataPath.parse "customer.roles[1]"
// => [ DataPathSegment.Name "customer"; DataPathSegment.Name "roles"; DataPathSegment.Index 1 ]
DataPath.parse "metadata[\"build.version\"]"
// => [ DataPathSegment.Name "metadata"; DataPathSegment.Name "build.version" ]The empty path "" addresses the root value.