Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.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#_Units Of Measurement - Fatal编程技术网

f#泛型类型上的泛型单位

f#泛型类型上的泛型单位,f#,units-of-measurement,F#,Units Of Measurement,是否可以定义一个通用于数据类型和度量单位的函数?例如,我想做什么,但没有编译(虽然即使没有度量单位也不会,但我相信我表达了我想做的事情): 我知道,对于这个特殊情况,我可以使用 let dropUnit (x : float<_>) = (float) x 让dropUnit(x:float)=(float)x 但是在写上述内容时,我开始思考一般情况。关于如何编写isValidUnitValue函数的具体问题,答案是: let inline isValidUnitValue my

是否可以定义一个通用于数据类型和度量单位的函数?例如,我想做什么,但没有编译(虽然即使没有度量单位也不会,但我相信我表达了我想做的事情):

我知道,对于这个特殊情况,我可以使用

let dropUnit (x : float<_>) = (float) x
让dropUnit(x:float)=(float)x

但是在写上述内容时,我开始思考一般情况。

关于如何编写
isValidUnitValue
函数的具体问题,答案是:

let inline isValidUnitValue myUnit = myUnit > LanguagePrimitives.GenericZero
所以你不需要定义一个歧视性的联盟

关于最初的问题,是否可以定义一个既通用于数据类型又通用于度量单位(如
dropUnit
)的函数,简短的回答是否定的。如果存在这样的函数,它将有一个签名,如
'a`)=
让ux=x*(LanguagePrimitives.GenericOne:'Num)
重新键入x:'Num

这类似于2),但不需要类型注释。其局限性在于它仅适用于数字类型,但通常情况下,这是计量单位的使用情况。

另一种选择是使用内联函数来伪造接口。
let isValidUnitValue myUnit =
   match myUnit with
       | Weight(x) -> (dropUnit x) > 0.
       | Volume(x) -> (dropUnit x) > 0.
let dropUnit (x : float<_>) = (float) x
let inline isValidUnitValue myUnit = myUnit > LanguagePrimitives.GenericZero
    type UnitDropper = 
        static member drop (x:sbyte<_>  ) = sbyte   x
        static member drop (x:int16<_>  ) = int16   x
        static member drop (x:int<_>    ) = int     x
        static member drop (x:int64<_>  ) = int64   x
        static member drop (x:decimal<_>) = decimal x
        static member drop (x:float32<_>) = float32 x
        static member drop (x:float<_>  ) = float   x

    [<Measure>] type m
    let x = UnitDropper.drop 2<m> + 3
> let inline dropUnitAndAdd3 x = UnitDropper.drop x + 3 ;;
-> error FS0041: A unique overload for method 'drop' could not be determined ...
    let inline retype (x:'a) : 'b = (# "" x : 'b #)

    [<Measure>] type m
    let x = retype 2<m> + 3
    let inline dropUnitAndAdd3 x = retype x + 3
let y = retype 2.0<m> + 3
    type DropUnit = DropUnit with
        static member ($) (DropUnit, x:sbyte<_>  ) = sbyte   x
        static member ($) (DropUnit, x:int16<_>  ) = int16   x
        static member ($) (DropUnit, x:int<_>    ) = int     x
        static member ($) (DropUnit, x:int64<_>  ) = int64   x
        static member ($) (DropUnit, x:decimal<_>) = decimal x
        static member ($) (DropUnit, x:float32<_>) = float32 x
        static member ($) (DropUnit, x:float<_>  ) = float   x

    let inline dropUnit x = DropUnit $ x

    [<Measure>] type m
    let x = dropUnit 2<m>   + 3
    let inline dropUnitAndAdd3 x = dropUnit x + 3
    let y = dropUnit 2.0<m> + 3   //fails at compile-time
    type MyNumericType<[<Measure 'U>]> =
        ...
        static member dropUoM (x:MyNumericType<_>) : MyNumericType = ...
        static member ($) (DropUnit, x:MyNumericType<_>) = MyNumericType.dropUoM(x)
    let inline retype (x: 'T) : 'U = (# "" x: 'U #)
    let inline stripUoM (x: '``Num<'M>``) =
        let _ = x * (LanguagePrimitives.GenericOne : 'Num)
        retype x :'Num