Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F#Ununit-函数内的reunit_F#_Units Of Measurement - Fatal编程技术网

F#Ununit-函数内的reunit

F#Ununit-函数内的reunit,f#,units-of-measurement,F#,Units Of Measurement,这个问题与这些问题密切相关(,) 我使用的是一个外部库,它还不能处理度量单位。我希望能够在传入值之前“取消统一”它们,然后在返回结果时“重新统一”它们 问题是我想避免被迫提前声明哪些单位 示例代码段 let ExternalNonUnitAwareFunction s = s + 1. let MyUnitAwareClient (s:float<'u>) = //' //1. this option "flattens" to no unit, or fixes to

这个问题与这些问题密切相关(,)

我使用的是一个外部库,它还不能处理度量单位。我希望能够在传入值之前“取消统一”它们,然后在返回结果时“重新统一”它们

问题是我想避免被迫提前声明哪些单位

示例代码段

let ExternalNonUnitAwareFunction s = s + 1.

let MyUnitAwareClient (s:float<'u>) =  //'
    //1. this option "flattens" to no unit, or fixes to first inferred unit
    //let (unit:float<'u>) = 1.0<_>  
    //2. this works fine, except for 0!
    let unit = s / (float s) 
    s |> float |> ExternalNonUnitAwareFunction |> (*) unit
让externalununitawarefunction s=s+1。

让MyUnitAwareClient(s:float现在,拳击和施法似乎有效:

let MyUnitAwareClient (s:float<'u>) =  
  let result = s |> float |> ExternalNonUnitAwareFunction
  (box result :?> float<'u>)
让MyUnitAwareClient(s:float)
但是,如果度量单位在发布之前进行了一些进一步的更改,我不会感到惊讶,这可能会打破这一点。您还可以制作更通用的版本,例如:

let reunit (f:float -> float) (v:float<'u>) =
  let unit = box 1. :?> float<'u>
  unit * (f (v/unit))
让我们重聚(f:float->float)(v:float
单位*(f(v/单位))
编辑

现在有一个
FloatWithMeasure
函数用于“转换为单位”:


为了好玩,这里正好相反:

let deunit (fn:float<'u> -> float<'v>) (v:float) =
    let unit = box 1. :?> float<'u>
    fn(v * unit) |> float

5月CTP/2010 Beta 1版对签名整数类型提供了度量单位支持——非常好,非常感谢!我非常喜欢第二个选项,不过我想我会称之为unitize(如memoize)。
#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 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>