F#度量单位,通用性问题 [英] F# Units of measure, problems with genericity

查看:65
本文介绍了F#度量单位,通用性问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(我是仍然 一击(用F#中的度量单位)

(I'm still banging on with units of measure in F#)

我在制作带有类型化"浮点数的通用"函数时遇到问题.

I'm having a problem making 'generic' functions which take 'typed' floats.

下面的模型类旨在根据因子'c'来显示位置上的累积错误.编译器不喜欢我在类型​​的正文中说"0.<'a>"(计量单位文字中的意外类型参数").

The following mockup class is intended to keep tabs on a cumulative error in position, based on a factor 'c'. The compiler doesn't like me saying 0.<'a> in the body of the type ("Unexpected type parameter in unit-of-measure literal").

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


我认为,另一个相关的问题仍然与通用"功能有关.


Another related question, I believe, still to do with 'generic' functions.

在下面的代码中,我试图做的是制作一个函数,该函数将接受任何类型的浮点数的#seq并将其应用于仅接受普通"浮点数的函数.第三行给出"值限制"错误,我看不到任何出路. (删除#可以解决问题,但我想避免为列表,序列,数组等写相同的东西.)

In the following code, what I am trying to do is make a function which will take a #seq of any type of floats and apply it to a function which only accepts 'vanilla' floats. The third line gives a 'Value Restriction' error, and I can't see any way out. (Removing the # solves the problem, but I'd like to avoid having to write the same thing for lists, seqs, arrays etc.)

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

推荐答案

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

You can change the first 'compiler no like' to

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

,编译器似乎很喜欢.

关于第二个问题,我没有看到与您相同的错误,并且

As for the second question, I am not seeing the same error as you, and this

[<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< _>的up恼有点令人讨厌,但我不确定是否有简便的方法可以摆脱它).

compiles for me (though the upcast to seq<_> is a little annoying, I am not sure if there is an easy way to get rid of it or not).

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

Aside, I think convention is to name units parameters 'u, 'v, ... rather than 'a, 'b, ...

这篇关于F#度量单位,通用性问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆