Skip to content

Generic TypeWithMeasure and TypeWithoutMeasure functions for adding units of measure on any type #452

@cloudRoutine

Description

@cloudRoutine

Idea 8401578: Generic TypeWithMeasure and TypeWithoutMeasure functions for adding units of measure on any type

Status : open
Submitted by exercitus vir on 6/13/2015 12:00:00 AM
2 votes

Currently, the Core.LanguagePrimitives module only provides the following functions to add units of measure to decimal, double (= float) and single (=float32), respectively:
DecimalWithMeasure : decimal -> decimal<'u>
Float32WithMeasure : float -> float<'u>
FloatWithMeasure : float32 -> float32<'u>
and the Core.Operators module overloaded functions for removing units of measure on decimal, double (= float) and single (=float32):
decimal : ^T -> decimal
float : ^T -> float
float32 : ^T -> float32
Even though all the other primitive numeric types are also annotated with [], you cannot use them to carry a unit of measure, because the needed conversion functions are missing. And since MeasureAnnotatedAbbreviation is a public attribute, we would should be able to add units of measure on any type.
So, I propose to add the following generic functions to the Core.LanguagePrimitives module as follows:
TypeWithMeasure<'T, 'U> : 'T -> 'U
TypeWithoutMeasure<'T, 'U>: 'U -> 'T
where 'U is 'T with the measure.
Currently, DecimalWithMeasure, Float32WithMeasure, FloatWithMeasure are all implemented using the same generic function:
let inline retype<'T,'U> (x:'T) : 'U = (# "" x : 'U #)
So TypeWithMeasure and TypeWithoutMeasure could simply reuse this function. I realize that retype might not be entirely safe, but implementors of custom types that can carry units of measure can then implement two type-safe functions:
//custom type
type SomeType = ...
//custom type that can carry measure
[]
type SomeType <[] 'm> = SomeType
//module with conversion functions for custom type
module SomeType =
let inline SomeTypeWithMeasure (withoutMeasure : SomeType) : SomeType<'m> = TypeWithMeasure withoutMeasure
let inline SomeWithoutMeasure (withMeasure : SomeType<'m>) : SomeType = TypeWithMeasure withMeasure

Archived Uservoice Comments

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions