只是为了好玩,这是相反的:
let deunit (fn:float<'u> -> float<'v>) (v:float) =
let unit = box 1. :?> float<'u>
fn(v * unit) |> float
测试 :
#light
[<Measure>]type mm
let reunit (fn:float -> float) (v:float<'u>) =
let unit = box 1. :?> float<'u>
unit * (fn(v/unit))
let deunit (fn:float<'u> -> float<'v>) (v:float) =
let unit = box 1. :?> float<'u>
fn(v * unit) |> float
let nounits v = v + 2.5 //function with no units
let withunits = reunit nounits //make it handle units (run with next line)
withunits 2.5<mm> //try it -> 5.0<mm>
let newnounits = deunit withunits //remove unit handling
newnounits 2.5 //try it -> 5.0<mm>
let withunits2 = reunit newnounits //reunit to another function
withunits2 2.5<mm^2> //try with different units
那个 #"(£$! 如果你let withunits = reunit nounits
自己运行它,就会出现价值限制错误。所以你必须使用使用 withunits 的行来运行它。我想这并不奇怪,你必须传入(v:float<'u>)
to reunit for F# 能够弄清楚'u 是什么。我猜可能会使重聚的兴趣有限...
更新:一个有点古怪的解决方法是传递“模型”值
let reunit2 (fn:float -> float) (model:float<'u>*float<'v>) =
let unitin = box 1. :?> float<'u>
let unitout = box 1. :?> float <'v>
(fun v -> (fn(v / unitin)) * unitout)
let withunits3 = reunit2 nounits (0.<mm>, 0.<mm^2>)
withunits3 3.5<mm>