F#度量单位,通用性问题

时间:2009-01-20 10:38:55

标签: f# units-of-measurement

still banging关于F#中的度量单位

我在制作'通用'函数时遇到问题,这些函数采用'typed'浮点数。

以下模型类旨在根据因子“c”监视位置累积错误。编译器不喜欢我说0.<'a>在类型的主体中(“度量单位字面量中的意外类型参数”)。

///Corrects cumulative error in position based on s and c
type Corrector(s_init:float<'a>) =
    let deltaS ds c = sin (ds / c) //incremental error function

    //mutable values
    let mutable nominal_s = s_init
    let mutable error_s = 0.<'a>  //<-- COMPILER NO LIKE

    ///Set new start pos and reset error to zero
    member sc.Reset(s) = 
        nominal_s <- s
        error_s <- 0.<'a>  //<-- COMPILER NO LIKE

    ///Pass in new pos and c to corrector, returns corrected s and current error    
    member sc.Next(s:float<'a>, c:float<'a>) = 
        let ds = s - nominal_s //distance since last request
        nominal_s <- s   //update nominal s
        error_s <- error_s + (deltaS ds c) //calculate cumulative error
        (nominal_s + error_s, error_s) //pass back tuple

我认为,另一个相关问题仍然与“通用”功能有关。

在下面的代码中,我要做的是创建一个函数,它将采用任何类型浮点数的#seq并将其应用于只接受'vanilla'浮点数的函数。第三行出现“Value Restriction”错误,我看不出任何出路。 (删除#解决了问题,但我想避免为列表,seqs,数组等编写相同的东西。)

[<Measure>] type km //define a unit of measure
let someFloatFn x = x + 1.2 //this is a function which takes 'vanilla' floats
let MapSeqToNonUnitFunction (x:#seq<float<'a>>) = Seq.map (float >> someFloatFn) x
let testList = [ 1 .. 4 ] |> List.map float |> List.map ((*) 1.0<km>)
MapSeqToNonUnitFunction testList

2 个答案:

答案 0 :(得分:1)

您可以将第一个'编译器不喜欢'更改为

let mutable error_s : float<'a> = 0.0<_>

并且编译器似乎喜欢这样。

至于第二个问题,我没有看到与你相同的错误,而且

[<Measure>] type km 
//define a unit of measure
let someFloatFn x = x + 1.2 //this is a function which takes 'vanilla' floats
let MapSeqToNonUnitFunction (x:seq<float<_>>) = Seq.map (float >> someFloatFn) x
let testList = [ 1 .. 4 ] |> List.map float |> List.map ((*) 1.0<km>)
let testList2 = testList :> seq<_>
let result = MapSeqToNonUnitFunction testList2
printfn "%A" result

为我编译(虽然向上搜索&lt; _&gt;有点烦人,我不确定是否有一种简单的方法可以摆脱它)。

除此之外,我认为惯例是命名单位参数'u,'v,...而不是'a,'b,......

答案 1 :(得分:0)

度量单位不能用作类型参数。这是因为编译期间编译器会将其擦除。这个问题很相似: F# Units of measure - 'lifting' values to float<something>