相关类型超过数据类型

时间:2018-01-31 04:17:46

标签: dependent-type ats

我在写一个只能在一周的某些日子里通过的功能时有点挣扎。我希望这会奏效:

datatype days = sunday | monday | tuesday | wednesday | thursday | friday | saturday

fn only_sunday{d:days | d == sunday}(d: days(d)): days(d) = d

但当然,days(d)从未被定义过。这似乎只会起作用,因为ATS有很多内置类型 - intint(int)等。

这也行不通,但也许只是语法错了?

typedef only_sunday = { d:days | d == sunday }

fn only_sunday(d: only_sunday): only_sunday = d

在重新审视Introduction to Programming in ATS的依赖类型章节后,我意识到这有效:

datatype days(int) =
  | sunday(0)
  | monday(1)
  | tuesday(2)
  | wednesday(3)
  | thursday(4)
  | friday(5)
  | saturday(6)

fn print_days{n:int}(d: days(n)): void =
  print_string(case+ d of
    | sunday() => "sunday"
    | monday() => "monday"
    | tuesday() => "tuesday"
    | wednesday() => "wednesday"
    | thursday() => "thursday"
    | friday() => "friday"
    | saturday() => "saturday")
overload print with print_days

fn sunday_only{n:int | n == 0}(d: days(n)): days(n) = d

implement main0() =
  println!("this typechecks: ", sunday_only(sunday))

但是,当然,n == 0表示“必须是星期日”比使用d == sunday等代码时更清楚一点。虽然将天数映射到数字似乎并不常见,但请考虑:

datatype toppings(int) = lettuce(0) | swiss_cheese(1) | mushrooms(2) | ...

在这种情况下,数字完全没有意义,因此如果您手头有数据类型定义,那么您只能将任何{n:int | n != 1} ... toppings(n)代码理解为反瑞士奶酪。如果你要编辑一个新的顶部

datatype toppings(int) = lettuce(0) | tomatoes(1) | swiss_cheese(2) | ...

然后,只有任何瑞士奶酪代码,1更新为2

是否有更具象征性的方式来使用依赖类型?

1 个答案:

答案 0 :(得分:2)

您可以尝试这样的事情:

stadef lettuce = 0
stadef swiss_cheese = 1
stadef mushrooms = 2

datatype
toppings(int) =
| lettuce(lettuce)
| swiss_cheese(swiss_cheese)
| mushrooms(mushrooms)