. Net – f#int.maxvalue is “not a valid constant expression”, but system Int32. What is maxvalue?

TL; Dr: the f# compiler interprets int as int operator in this context, such as determined by Eugene fotin and expanded upon by gene belitski The best solution is to use system int32. Maxvalue or unique type alias, as described below

Consider the following record types:

type User = {
    Username : string
}

I want the user name to be at least three characters long, so I use the stringlength property There is no maximum length, so I set it to int.maxvalue:

type User = {
    [<StringLength(int.MaxValue,MinimumLength=3)>]
    Username : string
}

This gave me the following errors:

Everything is peach, if I use system Int32 replaces:

type User = {
    [<StringLength(system.int32.MaxValue,MinimumLength=3)>]
    Username : string
}

It also compiles if I alias int:

type User = {
    [<StringLength(num.MaxValue,MinimumLength=3)>]
    Username : string
}
and num = int

Or fully qualified type:

type User = {
    [<StringLength(Microsoft.FSharp.Core.int.MaxValue,MinimumLength=3)>]
    Username : string
}

I checked the f# source and int is defined exactly as you would expect:

type int32 = system.int32
// Then,a few lines later…
type int = int32

What's going on? I assume that f# primitive types are interchangeable with other types in most cases, but it looks like something missing from my mental model

Solution

This is how f# type inference works in different contexts, where different syntactic entities coincidentally have the same name, if int can be any of the following:

>Function int:'t > the full name of int is Microsoft FSharp. Core. Operators. Int > type the full name of int = int32 Microsoft FSharp. Core. Int > type int & "measure > = full name is Microsoft FSharp. Core. int< _>

One way to demonstrate this work would be if we just entered

int;;

In FSI, we will get something similar

val it : (int -> int) = <fun:it@3>

In other words, it is a function that cannot be associated with its maxvalue property:

> int.MaxValue;;

int.MaxValue;;
----^^^^^^^^

... error FS0039: The field,constructor or member 'MaxValue' is not defined

The same applies to int32. When used in the context of an expression, it is inferred by FSI as another function with only signature (int – > int32)

Now let's talk about

type num = int

In this context, int is inferred as system Int32's type name abbreviation, so num is also a type abbreviation, but now there is no ambiguity in the name, so num.maxvalue is what we expect, and what we expect is in FSI

> num.MaxValue;;
val it : int = 2147483647

Finally, when you use Microsoft FSharp. Core. Int, you explicitly reference the type entity without any ambiguity, so it works as expected

Return to your use case attribute parameters - in this context, int is type inferred as part of an expression to provide parameter values, that is, as functions, unless you explicitly or indirectly set another interpretation

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>