如何创建其值只能在有效范围内的类型?

时间:2016-03-15 05:53:20

标签: f#

如何创建其值只能在有效范围内的类型?

大多数静态类型语言都提供数值类型,其中每种类型都支持一系列值。

int就是这种类型的一个例子。

支持以下内容:

  

使非法国家无法代表

如何创建一种类型,以便超出范围的值赋值在编译时导致错误?

例如: 类型PositiveInteger //范围是0到2,147,483,647

更新

我试过这个:

type PositiveInteger = private PInt of int with
    static member FromInt i =
       if i <= 0 then failwith "out of range" else PInt i

let isSuccessful = 
    PInt -1

然而,上面的代码仍然编译,当我希望它抛出&#34;超出范围&#34;在编译时。 可以说编译时不支持这个吗?

2 个答案:

答案 0 :(得分:6)

让我们继续这个例子(并将其扩展为正p&lt; =&gt; p&gt; 0

你可以随时使用一些数学(这里使用peano axioms的略微修改来定义正数自然数):

type PositiveInteger =
   | One
   | Succ of PositiveInteger

会有更大的范围

当然这有点难以使用:

let one = One
let two = Succ one
...
let rec add a b =
     match (a,b) with
     | (One, b)    -> Succ b
     | (Succ a, b) -> Succ (add a b)

这通常效率不高(虽然它常用于类型级别......如果语言支持它)

因此,大多数人可能会使用某种智能构造函数 fail-fast 方法:

type PositiveInteger = private PInt of int with
    static member FromInt i =
       if i <= 0 then failwith "out of range" else PInt i
如果你错过了with

,那么这个也应该编译
type PositiveInteger = 
    private | PInt of int
    static member FromInt i =
        if i <= 0 then failwith "out of range" else PInt i

答案 1 :(得分:1)

我通常使用静态函数来返回Result<T, Error>的实例,异常确实不是一个好的模式。