我刚开始学习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'
我做错了什么?有没有其他方法来构建这种类型?
非常感谢您的回答!
答案 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
功能,确保不会产生奇怪的周数。