Header menu logo Fabulous.AST

Units of Measure

Units of measure let you annotate numeric types with physical units that the compiler checks. Declare a measure with Measure, and attach one to a literal with ConstantMeasure.

Contents

#r "../../src/Fabulous.AST/bin/Release/netstandard2.1/publish/Fantomas.Core.dll"
#r "../../src/Fabulous.AST/bin/Release/netstandard2.1/publish/Fabulous.AST.dll"
#r "../../src/Fabulous.AST/bin/Release/netstandard2.1/publish/Fantomas.FCS.dll"

open Fabulous.AST
open type Fabulous.AST.Ast

Defining a Measure

A bare Measure declares a base unit:

Oak() {
    AnonymousModule() {
        Measure("cm")
        Measure("kg")
        Measure("s")
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
[<Measure>]
type cm

[<Measure>]
type kg

[<Measure>]
type s

Derived Measures

Build derived measures from powers and products of existing ones with MeasurePowerType, AppPrefix, and Tuple:

Oak() {
    AnonymousModule() {
        Measure("ml", MeasurePowerType("cm", Integer "3"))

        Measure("N", Tuple([ AppPrefix(LongIdent "kg", LongIdent "m"); MeasurePowerType("s", Integer "2") ], "/"))
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
[<Measure>]
type ml = cm^3

[<Measure>]
type N = kg<m> / s^2

Using a Measure

Annotate a numeric literal with ConstantMeasure:

Oak() { AnonymousModule() { Value("length", ConstantExpr(ConstantMeasure("10.0", MeasureSingle("cm")))) } }
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
let length = 10.0<cm>
namespace Fabulous
namespace Fabulous.AST
type Ast = class end
Multiple items
static member Ast.Oak: unit -> CollectionBuilder<Fantomas.Core.SyntaxOak.Oak,'marker>

--------------------
module Oak from Fabulous.AST
static member Ast.AnonymousModule: unit -> CollectionBuilder<Fantomas.Core.SyntaxOak.ModuleOrNamespaceNode,Fantomas.Core.SyntaxOak.ModuleDecl>
Multiple items
static member Ast.Measure: name: string * powerType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.TypeDefn>
static member Ast.Measure: name: string * powerType: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.TypeDefn>
static member Ast.Measure: name: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.TypeDefn>

--------------------
module Measure from Fabulous.AST

--------------------
type MeasureAttribute = inherit Attribute new: unit -> MeasureAttribute

--------------------
new: unit -> MeasureAttribute
type Gen = static member mkOak: root: WidgetBuilder<'node> -> 'node static member parse: source: string -> string + 1 overload static member run: oak: Oak -> string + 1 overload
<summary> Renders a widget tree to F# source and verifies the result. <c>mkOak</c> turns the root widget into a Fantomas node (recursively building its children), <c>run</c> formats that node to source (optionally with a config), and <c>parse</c> round-trips the source back through the parser to confirm it is syntactically valid. Designed for pipeline use, e.g. <c>widget |&gt; Gen.parse</c> or <c>widget |&gt; Gen.mkOak |&gt; Gen.run |&gt; Gen.parse</c>. </summary>
static member Gen.mkOak: root: WidgetBuilder<'node> -> 'node
static member Gen.run: oak: Fantomas.Core.SyntaxOak.Oak -> string
static member Gen.run: oak: Fantomas.Core.SyntaxOak.Oak * config: Fantomas.Core.FormatConfig -> string
val printfn: format: Printf.TextWriterFormat<'T> -> 'T
static member Ast.MeasurePowerType: value: string * rational: WidgetBuilder<Fantomas.Core.SyntaxOak.RationalConstNode> -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
static member Ast.MeasurePowerType: value: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> * rational: WidgetBuilder<Fantomas.Core.SyntaxOak.RationalConstNode> -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
static member Ast.Integer: value: int -> WidgetBuilder<Fantomas.Core.SyntaxOak.RationalConstNode>
static member Ast.Integer: value: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.RationalConstNode>
Multiple items
static member Ast.Tuple: items: string seq * exponent: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
static member Ast.Tuple: items: string seq -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
static member Ast.Tuple: items: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> seq * exponent: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
static member Ast.Tuple: items: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> seq -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>

--------------------
module Tuple from Fabulous.AST
static member Ast.AppPrefix: t: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> * postIdentifier: string seq * arguments: string seq -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
   (+0 other overloads)
static member Ast.AppPrefix: t: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> * argument: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
   (+0 other overloads)
static member Ast.AppPrefix: t: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> * postIdentifier: string * arguments: string seq -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
   (+0 other overloads)
static member Ast.AppPrefix: t: string * postIdentifier: string seq * arguments: string seq -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
   (+0 other overloads)
static member Ast.AppPrefix: t: string * postIdentifier: string * arguments: string seq -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
   (+0 other overloads)
static member Ast.AppPrefix: t: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> * postIdentifier: string seq * arguments: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
   (+0 other overloads)
static member Ast.AppPrefix: t: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> * postIdentifier: string * arguments: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
   (+0 other overloads)
static member Ast.AppPrefix: t: string * postIdentifier: string * arguments: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
   (+0 other overloads)
static member Ast.AppPrefix: t: string * postIdentifier: string seq * arguments: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
   (+0 other overloads)
static member Ast.AppPrefix: t: string * postIdentifier: string * argument: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
   (+0 other overloads)
static member Ast.LongIdent: value: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
static member Ast.LongIdent: value: string seq -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
static member Ast.Value: name: string * value: string * returnType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: string * returnType: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * returnType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * returnType: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Expr> * returnType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Expr> * returnType: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Expr> -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * returnType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.ConstantExpr: value: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Expr>
static member Ast.ConstantExpr: value: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> -> WidgetBuilder<Fantomas.Core.SyntaxOak.Expr>
Multiple items
static member Ast.ConstantMeasure: constant: string * measure: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Constant>
static member Ast.ConstantMeasure: constant: string * measure: WidgetBuilder<Fantomas.Core.SyntaxOak.Measure> -> WidgetBuilder<Fantomas.Core.SyntaxOak.Constant>
static member Ast.ConstantMeasure: constant: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * measure: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Constant>
static member Ast.ConstantMeasure: constant: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * measure: WidgetBuilder<Fantomas.Core.SyntaxOak.Measure> -> WidgetBuilder<Fantomas.Core.SyntaxOak.Constant>

--------------------
module ConstantMeasure from Fabulous.AST
static member Ast.MeasureSingle: value: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Measure>

Type something to start searching.