3

(私はまだ F# の測定単位に取り組んでいます)

「型付き」フロートを取る「汎用」関数の作成に問題があります。

次のモックアップ クラスは、係数 '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

もう1つの関連する質問は、まだ「ジェネリック」関数に関係していると思います。

次のコードで、私がやろうとしているのは、あらゆるタイプのフロートの #seq を受け取り、それを「バニラ」フロートのみを受け入れる関数に適用する関数を作成することです。3 行目で ' Value Restriction ' エラーが発生し、解決方法がわかりません。(#を削除すると問題は解決しますが、リスト、seq、配列などに同じことを書く必要は避けたいです。)

[<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
4

2 に答える 2

1

最初の「コンパイラが好きではない」を次のように変更できます

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

コンパイラはそれを気に入っているようです。

2 番目の質問については、あなたと同じエラーは表示されませんが、これは

[<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

私のためにコンパイルします(ただし、 seq<_> へのアップキャストは少し面倒ですが、それを取り除く簡単な方法があるかどうかはわかりません)。

余談ですが、慣習として、単位パラメーターには「a、」b、... ではなく、「u、」、「v」と名前を付けることがあると思います。

于 2009-01-20T20:41:01.360 に答える
0

測定単位はタイプパラメータとして使用できません。これは、コンパイル中にコンパイラによってが消去されるためです。この質問は非常に似ています: F#測定単位-'値を持ち上げてfloat<何か>

于 2009-01-20T11:33:33.977 に答える