Generics 如何统一这两个浮点函数?

Generics 如何统一这两个浮点函数?,generics,f#,numbers,type-conversion,type-inference,Generics,F#,Numbers,Type Conversion,Type Inference,我发现这是一种在一次数据传递中计算平均值和标准偏差的方法。我想让它为float32和float工作,我正努力用通用数字来纠正这个错误 module Seq = let inline private avgVarianceReducer toFloat (count, oldM, oldS) x = if count = 1 then 2, x, LanguagePrimitives.GenericZero else

我发现这是一种在一次数据传递中计算平均值和标准偏差的方法。我想让它为
float32
float
工作,我正努力用通用数字来纠正这个错误

module Seq =
    let inline private avgVarianceReducer toFloat (count, oldM, oldS) x =
        if count = 1 then
            2, x, LanguagePrimitives.GenericZero
        else
            let meanFree = x - oldM
            let newM = oldM + meanFree / (toFloat count)
            count + 1, newM, oldS + meanFree * (x - newM)

    let inline private avgVarianceWith toFloat source =
        match source |> Seq.fold (avgVarianceReducer toFloat) (1, LanguagePrimitives.GenericZero, LanguagePrimitives.GenericZero) with
        | 0, _, _ -> LanguagePrimitives.GenericZero, LanguagePrimitives.GenericZero
        | 1, mean, _ -> mean, LanguagePrimitives.GenericZero
        | n, mean, var -> mean, var / (n - 2 |> toFloat)

    let avgVariance source = source |> avgVarianceWith float
    let avgVariancef source = source |> avgVarianceWith float32
这对这两种类型都有效,但我有额外的
avgVariancef
,而且在调用时必须选择正确的一种

对我来说,中心问题是在
avgvarianceducer
中转换到正确类型的浮点,我通过传递正确的转换函数解决了这个问题。我尝试了
op_Explicit
的方法,但失败了

有人有更优雅的解决方案吗?

你试过了吗? 它包含一个通用数学模块和您正在寻找的通用
显式
函数

下面是您的代码的外观:

#r @"FsControl.dll"
#r @"FSharpPlus.dll"

open FSharpPlus
open FSharpPlus.Operators.GenericMath

module Seq =
    let inline private avgVarianceReducer (count, oldM, oldS) (x:'R) =
        if count = 1 then
            2, x, 0G
        else
            let meanFree = x - oldM
            let newM = oldM + meanFree / explicit count
            count + 1, newM, oldS + meanFree * (x - newM)

    let inline avgVariance source : 'R * 'R =
        match source |> Seq.fold avgVarianceReducer (1, 0G, 0G) with
        | 0, _, _ -> 0G, 0G
        | 1, mean, _ -> mean, 0G
        | n, mean, var -> mean, var / (n - 2 |> explicit)

    // or if you prefer specific functions
    let avgVarianceF32 source : float32 * float32 = avgVariance source
    let avgVarianceF   source : float   * float   = avgVariance source

    // it will work with other types as well
    let avgVarianceD source : decimal * decimal   = avgVariance source
事实上,您不需要函数
explicit
,您可以使用函数
from integral
,它对数字更为具体

您还可以浏览库的源代码,并仅提取特定案例所需的代码。

您尝试过吗? 它包含一个通用数学模块和您正在寻找的通用
显式
函数

下面是您的代码的外观:

#r @"FsControl.dll"
#r @"FSharpPlus.dll"

open FSharpPlus
open FSharpPlus.Operators.GenericMath

module Seq =
    let inline private avgVarianceReducer (count, oldM, oldS) (x:'R) =
        if count = 1 then
            2, x, 0G
        else
            let meanFree = x - oldM
            let newM = oldM + meanFree / explicit count
            count + 1, newM, oldS + meanFree * (x - newM)

    let inline avgVariance source : 'R * 'R =
        match source |> Seq.fold avgVarianceReducer (1, 0G, 0G) with
        | 0, _, _ -> 0G, 0G
        | 1, mean, _ -> mean, 0G
        | n, mean, var -> mean, var / (n - 2 |> explicit)

    // or if you prefer specific functions
    let avgVarianceF32 source : float32 * float32 = avgVariance source
    let avgVarianceF   source : float   * float   = avgVariance source

    // it will work with other types as well
    let avgVarianceD source : decimal * decimal   = avgVariance source
事实上,您不需要函数
explicit
,您可以使用函数
from integral
,它对数字更为具体

您还可以浏览库的源代码,并仅提取特定案例所需的代码