Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# Unit of Measure, Casting without losing the measure type

Is there built in version of the type casting functions that preserves units and if not how would I make them? So for example with this code how would I cast intWithSecondsMeasure to a float without losing the measure or multiplying by 1.0<s>?

[<Measure>] type s
let intWithSecondsMeasure = 1<s>
let justAFloat = float intWithSecondsMeasure 
like image 603
gradbot Avatar asked Dec 12 '09 18:12

gradbot


2 Answers

The answer provided by @kvb certainly works, but I'd prefer not to use the unbox operator for this conversion. There's a better, built in way that I think should be compiled as a NOP to IL (I haven't checked but unbox is probably going to end up as a unbox instruction in IL and thus adds a runtime type check).

The preferred way to do unit conversions in F# is LanguagePrimitives.TypeWithMeasure (MSDN).

let inline float32toFloat (x:float32<'u>) : float<'u> = 
    x |> float |> LanguagePrimitives.FloatWithMeasure
like image 105
Johannes Rudolph Avatar answered Oct 18 '22 19:10

Johannes Rudolph


I don't think that there's a built-in way to do it, but you can easily define your own unit-preserving conversion function:

let float_unit (x:int<'u>) : float<'u> = unbox float x
let floatWithSecondsMeasure = float_unit intWithSecondsMeasure
like image 8
kvb Avatar answered Oct 18 '22 19:10

kvb