在Haskell中键入整数的构造函数

时间:2013-11-26 10:19:24

标签: haskell types typeclass

我刚开始学习Haskell而且我遇到了以下问题:

我想创建一种日历周,即从1到52的数字。 这就是我尝试这个的原因:

data CalendarWeek = 1 | 2 | ... | 52 deriving (Eq, Order, Show)

那么它可以在这里使用:

data Offer = Offer CalendarWeek Day Offer String deriving (Eq, Order, Show)

但是,GHC只打印出以下错误:

parse error on input `1'

我做错了什么?有没有其他方法来构建这种类型?

非常感谢您的回答!

1 个答案:

答案 0 :(得分:5)

扩展我的评论:

我很确定你不能只有数字组成的名字。如果你真的想按自己的方式去做,你可以做到

data CalendarWeek = W1 | W2 | W3 | … | W52 | W53 deriving (Eq, Order, Show)

(请记住,有些年份有53周,最后是2009年。)

但是,我不建议这样做。首先,它是很多打字,并且无论如何,当以这种方式做事时,很难将周数视为数字。我建议做什么

data CalendarWeek = Week Int

然后你可以定义一个像

这样的函数
mkWeek :: Int -> CalendarWeek
mkWeek number =
  if number >= 1 && number <= 53
     then Week number
     else error "Not a valid week number!"

这会导致mkWeek 47返回值Week 47,而mkWeek 112会使您的程序失效。在一个真实的程序中,你可能不想在这里吹你的程序,但你做的是取决于情况。

同样地,每当你工作几周时,你需要确保该值不会溢出,但这是微不足道的(如果你通过mkWeek,你会得到检查免费电话)

当然,为了使您的方法与您建议的方法一样安全,您需要编写一堆测试。应测试处理周数的所有函数,以便它们不会意外返回Week 975。而且,如果你将它设计为一​​个单独的模块,你应该导出Week构造函数,因为这样做会允许任何人创建任何疯狂的周值。相反,强迫每个人使用您的mkWeek功能,确保不会产生奇怪的周数。