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#计算平均值的通用函数_F# - Fatal编程技术网

F#计算平均值的通用函数

F#计算平均值的通用函数,f#,F#,如何编写通用F#函数来计算集合的平均值? 我试过: 这对于浮点和小数似乎很好,但对于int却出人意料地不起作用,错误是类型“int”不支持运算符“DivideByInt”,首先,该函数已经存在于F#中,并被称为Seq.average。如果你这样做只是为了拥有这个功能,你现在可以停止阅读了。如果您将此作为个人学习练习,请继续阅读。:-) 答案如下: 如果类型支持DivideByInt,则该类型支持精确除法(浮点除法),而不是整数除法,整数除法将向下舍入到最接近的整数结果 仅当元素类型支持精确划分时

如何编写通用F#函数来计算集合的平均值? 我试过:


这对于浮点和小数似乎很好,但对于
int
却出人意料地不起作用,错误是
类型“int”不支持运算符“DivideByInt”
,首先,该函数已经存在于F#中,并被称为
Seq.average
。如果你这样做只是为了拥有这个功能,你现在可以停止阅读了。如果您将此作为个人学习练习,请继续阅读。:-)

答案如下:

如果类型支持DivideByInt,则该类型支持精确除法(浮点除法),而不是整数除法,整数除法将向下舍入到最接近的整数结果

仅当元素类型支持精确划分时,才使用Seq.average work之类的函数。如果尝试将Seq.average与整数序列一起使用,则会出现一个错误,指示元素类型必须实现DivideByInt。通常,您可以通过使用Seq.averageBy并向浮点值添加强制转换来解决此错误

因此,要使
mean
函数处理整数,需要将其编写如下:

let intMean (x : int seq) = 
    let length = x |> Seq.length
    let sum = x |> Seq.map float |> Seq.sum
    LanguagePrimitives.DivideByInt sum length

这是创建通用
mean
函数的一种方法

首先创建一个更通用的divideByInt

type Helper = Helper of int with
    static member (&/)(Helper b, a) = a /          b 
    static member (&/)(Helper b, a) = a / (float   b)
    static member (&/)(Helper b, a) = a / (decimal b)

let inline divideByInt a b = Helper b &/ a
此版本的
divideByInt
float
decimal
int
配合使用

然后像在原始解决方案中一样使用它:

let inline mean x = 
    let length = x |> Seq.length
    let sum    = x |> Seq.sum
    divideByInt sum length
然后像这样测试它:

mean [5. ; 3.] |> printfn "%A"   // 4.0
mean [5  ; 3 ] |> printfn "%A"   // 4

请注意,对序列求和然后除以长度容易出现溢出错误。最好使用增量算法,例如,从中实现一个算法

例如:

let inline mean xs =
    xs |> Seq.map float
       |> Seq.fold (fun (mean, n) x -> mean + (x-mean) / (float n), n+1) (0.0, 1)
       |> fst

所以不能编写一个通用函数来计算int、float、decimal的平均值?@stt106我的解决方案就是这样做的。
let inline mean xs =
    xs |> Seq.map float
       |> Seq.fold (fun (mean, n) x -> mean + (x-mean) / (float n), n+1) (0.0, 1)
       |> fst