首页 > 解决方案 > OCaml 中有没有办法在记录中声明一个整数,它是一些整数的间隔?

问题描述

我遇到了这个问题,我不得不:将类型日期定义为三元组,其中第一个组件是表示为整数的年份,第二个组件是表示月份的区间 [1..12] 中的整数,最后一个组件表示带有整数的一天。

type date = { year: int; month: int; day:int};;

{year = 2012; month = 12; day = 21};;

这很好用,但对于参数月,我需要从 1 到 12 的整数作为输入。

标签: ocaml

解决方案


如果您想要几个月只使用一个变体并枚举整个月。你可以对天数做同样的事情,但我会避免它。

如果您想要一个更一般的概念,例如范围类型:您不希望这样,因为月份有 30 天或 31 天,而二月有 28-29 天,具体取决于闰年,所以它是依赖范围......如果这个检查可用你想要的范围呢?您需要的检查非常具体:举个例子,我只在 cpp 中看到了这个带有扩展名的内容,并且您被迫在范围内使用 int (非常没用)。因为这个扩展需要静态 int 你不能真正用于日期。OCaml 不能这样做,因为所有 int 都不是int30 也不是 31。通常的解决方法是创建一个函数,该函数需要三个 int 验证它们是否在有效范围内并返回date option,并使其从外部变为私有,这样你就不能破坏不变的。我们称之为智能构造函数。

module SafeDate : sig
    type date = private { year: int; month: int; day:int}
    val create: int -> int -> int -> date option
end = struct
    type date = { year: int; month: int; day:int}
    let create year month day = if (* put formula/code to say if correct *) then Some{year; month; day} else None
end

推荐阅读