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
Generics 使用数值泛型获取本机数值类型的最小/最大值,Int32.MaxValue不';似乎不存在_Generics_F# - Fatal编程技术网

Generics 使用数值泛型获取本机数值类型的最小/最大值,Int32.MaxValue不';似乎不存在

Generics 使用数值泛型获取本机数值类型的最小/最大值,Int32.MaxValue不';似乎不存在,generics,f#,Generics,F#,我需要一个数值通用函数,可以访问数值类型的MinValue和MaxValue。因为所有的BCL类型都有这些成员,我想我可以这样写: let inline zeroOrMax(x: ^a) = match x with | a when a = LanguagePrimitives.GenericZero -> x | a when a = LanguagePrimitives.GenericOne -> let maxVal = (^a: (

我需要一个数值通用函数,可以访问数值类型的
MinValue
MaxValue
。因为所有的BCL类型都有这些成员,我想我可以这样写:

let inline zeroOrMax(x: ^a) =
    match x with
    | a when a = LanguagePrimitives.GenericZero -> x
    | a when a = LanguagePrimitives.GenericOne -> 
        let maxVal = (^a: (static member MaxValue : ^a) ())  
        maxVal 
    | a when -a = LanguagePrimitives.GenericOne -> 
        let maxVal = (^a: (static member MaxValue : ^a) ())  
        -maxVal 
    | _ -> ...
此函数将为您提供基础类型的零或(负/正)最大值

当我创建自己的类型实现
MaxValue
,但
Int32
Int64
等具有静态成员
MaxValue
MinValue
时,我会不断得到静态编译错误,该参数没有表示静态成员:

let test (x: int64) =
    // error FS0001: The type 'int64' does not support the operator 'get_MaxValue'
    zeroOrMax x

我想这是因为F#特别对待这些类型。或者我只是需要一种不同的语法。在保持数值泛型和访问基础类型的最小/最大值的同时,是否有办法解决此问题?

静态解析的类型成员约束不考虑字段

如注释中所述,您可以使用create这样的泛型函数,它通过为每个已知类型指定重载来完成您想要的任务

以下是“独立”版本的:

开放系统
键入MaxValue=MaxValue并加上
静态成员($)((单位:,最大值)=()
静态成员($)(u0:bool,0:MaxValue)=true
静态成员($)(u:char,u:MaxValue)=char.MaxValue
静态成员($)(u:byte,u:MaxValue)=byte.MaxValue
静态成员($)(yte:sbyte,yte:MaxValue)=sbyte.MaxValue
静态成员($)(quot:float,quot:MaxValue)=Double.MaxValue
静态成员($)(u:int16,u:MaxValue)=int16.MaxValue
静态成员($)(\u0:int,\u0:MaxValue)=Int32.MaxValue
静态成员($)(u:int64,u:MaxValue)=int64.MaxValue
静态成员($)(u:float32,u:MaxValue)=Single.MaxValue
静态成员($)(uint16,uint16:MaxValue)=uint16.MaxValue
静态成员($)(u3;:uint32,3;:MaxValue)=uint32.MaxValue
静态成员($)(u0:uint64,0:MaxValue)=uint64.MaxValue
静态成员($)(quo:decimal,quo:MaxValue)=decimal.MaxValue
静态成员($)(u:DateTime,u:MaxValue)=DateTime.MaxValue
静态成员($)(u:DateTimeOffset,u:MaxValue)=DateTimeOffset.MaxValue
静态成员($)(quo:TimeSpan,quo:MaxValue)=TimeSpan.MaxValue

让内联maxValue():'r=Unchecked.defaultof
int64.maxValue
是一个成员常量,而不是一个属性。@fyodor ouch,dejavu,感觉就像我之前看到的那样。我猜没有比这更简单的解决办法了?不,没有办法。我创建了一个这样做的。你可以使用它,也可以复制那里的代码。@Gustavo,有趣的方法。我是按照这些思路思考的(我希望把一些事情放在一起,我想这还不会发生)。另一种欺骗系统的方式导致了F#的奇怪(或不是?)行为。有趣的错误报告,一如既往。我将从该泛型函数中添加一些代码作为答案。
open System

type MaxValue = MaxValue with
    static member ($) (_:unit          , _:MaxValue) = ()
    static member ($) (_:bool          , _:MaxValue) = true
    static member ($) (_:char          , _:MaxValue) = Char.MaxValue
    static member ($) (_:byte          , _:MaxValue) = Byte.MaxValue
    static member ($) (_:sbyte         , _:MaxValue) = SByte.MaxValue
    static member ($) (_:float         , _:MaxValue) = Double.MaxValue
    static member ($) (_:int16         , _:MaxValue) = Int16.MaxValue
    static member ($) (_:int           , _:MaxValue) = Int32.MaxValue
    static member ($) (_:int64         , _:MaxValue) = Int64.MaxValue
    static member ($) (_:float32       , _:MaxValue) = Single.MaxValue
    static member ($) (_:uint16        , _:MaxValue) = UInt16.MaxValue
    static member ($) (_:uint32        , _:MaxValue) = UInt32.MaxValue
    static member ($) (_:uint64        , _:MaxValue) = UInt64.MaxValue
    static member ($) (_:decimal       , _:MaxValue) = Decimal.MaxValue
    static member ($) (_:DateTime      , _:MaxValue) = DateTime.MaxValue
    static member ($) (_:DateTimeOffset, _:MaxValue) = DateTimeOffset.MaxValue
    static member ($) (_:TimeSpan      , _:MaxValue) = TimeSpan.MaxValue

let inline maxValue() :'r =  Unchecked.defaultof<'r> $ MaxValue

type MaxValue with
    static member inline ($) ((_:'a*'b         ), _:MaxValue) = maxValue(), maxValue()
    static member inline ($) ((_:'a*'b*'c      ), _:MaxValue) = maxValue(), maxValue(), maxValue()
    static member inline ($) ((_:'a*'b*'c*'d   ), _:MaxValue) = maxValue(), maxValue(), maxValue(), maxValue()
    static member inline ($) ((_:'a*'b*'c*'d*'e), _:MaxValue) = maxValue(), maxValue(), maxValue(), maxValue(), maxValue()

// Usage
let x:int  = maxValue()
// val x : int = 2147483647

let y:int * float *TimeSpan = maxValue()
// val y : int * float * TimeSpan = (2147483647, 1.797693135e+308, 10675199.02:48:05.4775807)