Reputation: 53
I am calling external function requiring float[]
, but my array is float<m>[]
.
How could I strip the unit of measure from array?
I need something like the function below, but this does not compile.
And I would like to avoid any iterating or duplicating of the array, as float<m>
and float
values are identical...
let demeasure (arr:float<m>[]): float[] = float[] (arr)
Upvotes: 5
Views: 513
Reputation: 26184
Here's a generic solution for any numeric type, any unit of measure but for Arrays only. If we had Higher Kinds it could be made generic over the container as well:
let inline retype (x: 'T) : 'U = (# "" x: 'U #)
module Array =
let inline stripUoM (x: '``Num<'M>`` []) =
let _ = Unchecked.defaultof<'``Num<'M>``> * (LanguagePrimitives.GenericOne : 'Num)
retype x :'Num []
// Usage
[<Measure>]type m
let x = [|34.0<m>; 9.0<m>; 42.0<m> |] |> Array.stripUoM
// val x : float [] = [|34.0; 9.0; 42.0|]
let y = [|34<m>; 9<m>; 42<m> |] |> Array.stripUoM
// val y : int [] = [|34; 9; 42|]
Upvotes: 2
Reputation: 4139
let demeasure (arr: float<m>[]) = arr |> Array.map (fun i -> float i)
Upvotes: 1
Reputation: 118865
I believe that a cast to obj
, followed by a dynamic cast to float[]
would work, e.g.
(arr :> obj) :?> float[]
because there is no runtime representation.
Possibly see also
F# Units of measure - 'lifting' values to float<something>
How to generically remove F# Units of measure
Upvotes: 4
Reputation: 16782
[<Measure>]type m
let f (arr : float[]) : float = 0.0
let arr = [|1.0<m>|]
f (unbox (box arr))
Upvotes: 1