From 90885f3bff2e45c6984210b2a583bde6fc2b2948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Melvyn=20La=C3=AFly?= Date: Sun, 7 Aug 2022 11:07:52 +0200 Subject: [PATCH] Add documentation sections for inline schemas --- docs/library/JsonProvider.fsx | 79 ++++++++++++++++++++++++++++++++++ docs/library/XmlProvider.fsx | 81 +++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) diff --git a/docs/library/JsonProvider.fsx b/docs/library/JsonProvider.fsx index 3750f4e32..6f1a261d7 100644 --- a/docs/library/JsonProvider.fsx +++ b/docs/library/JsonProvider.fsx @@ -189,6 +189,85 @@ This is not a standard feature of JSON, but it can be really convenient, e.g. to annotate each sample when using multiple ones. *) +(** +## Type inference hints / inline schemas + +Starting with version 4.2.10 of this package, it's possible to enable basic type annotations +directly in the sample used by the provider, to complete or to override type inference. +(Only basic types are supported. See the reference documentation of the provider for the full list) + +This feature is disabled by default and has to be explicitly enabled with the `InferenceMode` +static parameter. + +Let's consider an example where this can be useful: + +*) + +type AmbiguousEntity = + JsonProvider +let code = (AmbiguousEntity.GetSamples()[1]).Code +let length = (AmbiguousEntity.GetSamples()[1]).Length + +(*** include-fsi-merged-output ***) + +(** +In the previous example, `Code` is inferred as a `float`, +even though it looks more like it should be a `string`. +(`4E5` is interpreted as an exponential float notation instead of a string) + +Now let's enable inline schemas: +*) + +open FSharp.Data.Runtime.StructuralInference + +type AmbiguousEntity2 = + JsonProvider", "length":"typeof>" } + { "code":"123", "length":"42" } + { "code":"4E5", "length":"1.83" } + """, + SampleIsList = true, + InferenceMode = InferenceMode.ValuesAndInlineSchemasOverrides> +let code2 = (AmbiguousEntity2.GetSamples()[1]).Code +let length2 = (AmbiguousEntity2.GetSamples()[1]).Length + +(*** include-fsi-merged-output ***) + +(** +With the `ValuesAndInlineSchemasOverrides` inference mode, the `typeof` inline schema +takes priority over the type inferred from other values. +`Code` is now a `string`, as we wanted it to be! + +Note that an alternative to obtain the same result would have been to replace all the `Code` values +in the samples with unambiguous string values. (But this can be very cumbersome, especially with big samples) + +If we had used the `ValuesAndInlineSchemasHints` inference mode instead, our inline schema +would have had the same precedence as the types inferred from other values, and `Code` +would have been inferred as a choice between either a number or a string, +exactly as if we had added another sample with an unambiguous string value for `Code`. + +You can use either angle brackets `<>` or curly brackets `{}` when defining inline schemas. + +### Units of measure + +Inline schemas also enable support for units of measure. + +In the previous example, the `Length` property is now inferred as a `float` +with the `metre` unit of measure (from the default SI units). + +Warning: units of measures are discarded when merged with types without a unit or with a different unit. +As mentioned previously, with the `ValuesAndInlineSchemasHints` inference mode, +inline schemas types are merged with other inferred types with the same precedence. +Since values-inferred types never have units, inline-schemas-inferred types will lose their +unit if the sample contains other values... + +*) + (** ## Loading WorldBank data diff --git a/docs/library/XmlProvider.fsx b/docs/library/XmlProvider.fsx index 3b5e91cd9..bd71471d2 100644 --- a/docs/library/XmlProvider.fsx +++ b/docs/library/XmlProvider.fsx @@ -128,7 +128,86 @@ for v in Test.GetSample().Values do The type provider generates a property `Values` that returns an array with the values - as the `` nodes do not contain any attributes or children, they are turned into `int` values and so the `Values` property returns just `int[]`! +*) + +(** +## Type inference hints / inline schemas + +Starting with version 4.2.10 of this package, it's possible to enable basic type annotations +directly in the sample used by the provider, to complete or to override type inference. +(Only basic types are supported. See the reference documentation of the provider for the full list) + +This feature is disabled by default and has to be explicitly enabled with the `InferenceMode` +static parameter. + +Let's consider an example where this can be useful: + +*) + +type AmbiguousEntity = + XmlProvider + + + """, + SampleIsList = true> +let code = (AmbiguousEntity.GetSamples()[1]).Code +let length = (AmbiguousEntity.GetSamples()[1]).Length + +(*** include-fsi-merged-output ***) + +(** +In the previous example, `Code` is inferred as a `float`, +even though it looks more like it should be a `string`. +(`4E5` is interpreted as an exponential float notation instead of a string) + +Now let's enable inline schemas: +*) + +open FSharp.Data.Runtime.StructuralInference +type AmbiguousEntity2 = + XmlProvider + + + """, + SampleIsList = true, + InferenceMode = InferenceMode.ValuesAndInlineSchemasOverrides> +let code2 = (AmbiguousEntity2.GetSamples()[1]).Code +let length2 = (AmbiguousEntity2.GetSamples()[1]).Length + +(*** include-fsi-merged-output ***) + +(** +With the `ValuesAndInlineSchemasOverrides` inference mode, the `typeof{string}` inline schema +takes priority over the type inferred from other values. +`Code` is now a `string`, as we wanted it to be! + +Note that an alternative to obtain the same result would have been to replace all the `Code` values +in the samples with unambiguous string values. (But this can be very cumbersome, especially with big samples) + +If we had used the `ValuesAndInlineSchemasHints` inference mode instead, our inline schema +would have had the same precedence as the types inferred from other values, and `Code` +would have been inferred as a choice between either a number or a string, +exactly as if we had added another sample with an unambiguous string value for `Code`. + +### Units of measure + +Inline schemas also enable support for units of measure. + +In the previous example, the `Length` property is now inferred as a `float` +with the `metre` unit of measure (from the default SI units). + +Warning: units of measures are discarded when merged with types without a unit or with a different unit. +As mentioned previously, with the `ValuesAndInlineSchemasHints` inference mode, +inline schemas types are merged with other inferred types with the same precedence. +Since values-inferred types never have units, inline-schemas-inferred types will lose their +unit if the sample contains other values... + +*) + +(** ## Processing philosophers In this section we look at an example that demonstrates how the type provider works @@ -648,6 +727,8 @@ Focusing on element shapes let us generate a type that should be essentially the inferred from a significant set of valid samples. This allows a smooth transition (replacing `Sample` with `Schema`) when a schema becomes available. +Note that inline schemas (values of the form `typeof{...}`) are not supported inside XSD documents. + ## Related articles * [Using JSON provider in a library](JsonProvider.html#jsonlib) also applies to XML type provider