Я не уверен, что понимаю, что вы подразумеваете под, нельзя использовать в качестве параметров типа, потому что это работает: let fn (a: float <'a>) (b: float <' a>) = a * b

( ещетреск  с единицами измерения в 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

В следующем коде я пытаюсь создать функцию, которая будет принимать #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

Ответы на вопрос(2)

Решение Вопроса

и компилятору, похоже, это нравится.

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

Что касается второго вопроса, я не вижу ту же ошибку, что и вы, и это

компилирует для меня (хотя переход на 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<_>>) = 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

Кроме того, я думаю, что соглашение заключается в том, чтобы называть единицы измерения параметрами 'u,' v, ... вместо 'a,' b, ...

Я оставлю это в качестве ответа, так как он ответил на две трети моего вопроса. И спасибо за напоминание о соглашении об именах. Я бы тоже хотел избежать ударов.

 Benjol16 февр. 2009 г., 22:05
Единицы измерения не могут использоваться в качестве параметров типа. Это потому, что они стираются компилятором во время компиляции. Этот вопрос очень похож:
 Benjol20 янв. 2009 г., 12:54
Я не уверен, что понимаю, что вы подразумеваете под, нельзя использовать в качестве параметров типа, потому что это работает: let fn (a: float <'a>) (b: float <' a>) = a * b
 Benjol20 янв. 2009 г., 13:03
F # Единицы измерения, проблемы с универсальн

Ваш ответ на вопрос