5 people like it.
Like the snippet!
General power function with units
The snippet demonstrates how to write a general power function that has correct type involving units-of-measure. The function uses numbers represented using types. The snippet is mainly an example of what can be done (not recommended for the real world).
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
|
[<Measure>] type cm
// Represents a number with units of measure powered to the
// number's value (e.g "(S (S O))" has type Num<cm, cm^3>)
type Num<[<Measure>] 'M, [<Measure>] 'N> =
| O_ of int * float<'N>
| S_ of int * Num<'M, 'N / 'M>
// Constructors that hide that simplify the creation
let O : Num<'M, 'M> = O_ (1, 0.0<_>)
let S n = match n with O_(i, _) | S_(i, _) -> S_(i + 1, n)
// Type-safe power function with units of measure
let pow (x:float<'M>) ((O_(i, _) | S_(i, _)):Num<'M, 'M 'N>) : float<'M 'N> =
// Unsafe hacky implementation, which is hidden
// from the user (for simplicity)
unbox ((float x) ** float i)
let res = pow 2.0<cm> (S (S O))
|
Multiple items
type MeasureAttribute =
inherit Attribute
new : unit -> MeasureAttribute
Full name: Microsoft.FSharp.Core.MeasureAttribute
--------------------
new : unit -> MeasureAttribute
[<Measure>]
type cm
Full name: Script.cm
type Num<'M,'N> =
| O_ of int * float<'N>
| S_ of int * Num<'M,'N/'M>
Full name: Script.Num<_,_>
union case Num.O_: int * float<'N> -> Num<'M,'N>
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
Multiple items
val float : value:'T -> float (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.float
--------------------
type float = System.Double
Full name: Microsoft.FSharp.Core.float
--------------------
type float<'Measure> = float
Full name: Microsoft.FSharp.Core.float<_>
union case Num.S_: int * Num<'M,'N/'M> -> Num<'M,'N>
val O : Num<'M,'M>
Full name: Script.O
val S : n:Num<'u,'v> -> Num<'u,'u 'v>
Full name: Script.S
val n : Num<'u,'v>
val i : int
val pow : x:float<'M> -> Num<'M,'N> -> float<'N>
Full name: Script.pow
val x : float<'M>
val unbox : value:obj -> 'T
Full name: Microsoft.FSharp.Core.Operators.unbox
val res : float<cm ^ 3>
Full name: Script.res
More information