简体   繁体   English

在F#中,是否可以在单个案例区分联合中限制值的范围?

[英]In F#, is it possible to limit the range of values in a single case discriminated union?

In the example below, I want every uint64 to be allowed except zero. 在下面的示例中,我希望除零之外允许每个uint64。

type Foo =
    | Foo of uint64

let foo = Foo(5UL) // OK
let bar = Foo(-1)  // Compiler error
let bad = Foo(0UL) // I want this to be a compiler error

To the best of my knowledge, you can't directly place bounds on the values (if someone else knows otherwise, please do let us know). 据我所知,你不能直接对价值观进行限制(如果其他人不知道,请告诉我们)。 I think that is something referred to as 'dependent types', which I don't believe F# supports, at least not currently. 认为这就是所谓的“依赖类型”,我不相信F#支持,至少目前不支持。

I'm guessing you're already well aware of the following, but for the sake of anyone else taking a look, I'll discuss how you might handle this at runtime: The easiest way to do this I believe would essentially be to make the type private and expose only a getFoo function that does custom validation at that time. 我猜你已经很清楚以下内容,但为了让其他人看一看,我将讨论你如何在运行时处理这个问题:最简单的方法我认为最简单的方法就是制作private类型并且只公开一个getFoo函数,该函数在那时进行自定义验证。 Depending on what you want, you would either wrap it in an option or throw an exception when the wrong number is passed in. Eg 根据您的需要,您可以将其包装在一个选项中,或者在传入错误的数字时抛出异常。例如

type private FooWithException = 
    | Foo of uint64

let getFooWithException (x: uint64) = 
    if x = 0 then
        failwith "x was zero"
    else
        Foo x

or 要么

type private FooOption = 
    | Foo of uint64 option

let tryGetFoo (x: uint64) = 
    if x = 0UL then
        None
    else
        Some(x)

You may also find this page at F# for Fun and Profit useful. 您也可以在F#的Fun和Profit 页面找到此页面

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM