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