haskell枚举 - 如果值构造函数需要值而不是nullary,该怎么办?给出了需求方案

Opt*_*ght 2 enums haskell derived derived-types derived-instances

LYAH派生实例中说"所有的值构造函数都是无效的(不带参数,即字段),我们可以将它作为Enum类型类的一部分."

数据日=星期一| 星期二| 星期三| 星期四| 星期五| 星期六| 星期日
派生(Eq,Ord,Show,Read,Bounded,Enum)

现在,如果我需要几个月,它就会

数据月= 1月| 二月| 三月| 四月| 五月| 六月| 七月| 八月|九月| 十月| 11月| 12月
推导(Eq,Ord,Show,Read,Bounded,Enum)

我的问题是:(1)每月存储最大天数值的位置?(2)如果是闰年,如何提及和控制2月份,那么2月份的maxDays为29天,否则为28天?

在Java中,可以像下面给出的代码:

公共枚举月份{
1月(31),
2月(29日),
3月(31日),
4月(30日),
5月(31日),
6月(30日),
7月(31日),
8月(31日),
9月(30日),
10月(31),
十一月(30),
十二月(31)
,;
private int maxDays; //实例变量
private(int maxDays){//构造函数总是私有
this.maxDays = maxDays;
}
公众诠释getMaxDays(){
返回maxDays;
}

pyr*_*ade 7

这应该工作.

data Month = January | February | March | April | May
           | June | July | August |September | October
           | November | December
           deriving (Eq, Ord, Show, Read, Bounded, Enum)

type Year = Int

isLeapYear :: Year -> Bool
isLeapYear year = year `mod` 4 == 0 && (year `mod` 100 /= 0 || year `mod` 400 == 0)

getMaxDays :: Year -> Month -> Int
getMaxDays _ January = 31

getMaxDays year February
    | isLeapYear year = 29
    | otherwise = 28

getMaxDays _ March = 31
getMaxDays _ April = 30
getMaxDays _ May = 31
getMaxDays _ June = 30
getMaxDays _ July = 31
getMaxDays _ August = 31
getMaxDays _ September = 30
getMaxDays _ October = 31
getMaxDays _ November = 30
getMaxDays _ December = 31
Run Code Online (Sandbox Code Playgroud)


Anu*_*ain 5

为什么你需要Month成为一个Enum?在我看来,你试图在代码中强制使用OO样式,这不是一个好主意.面向Java面向对象的编写代码风格并不能完全转换为像Haskell这样的函数式语言.

在OO中,您将数据结构和该数据的所有相关操作捆绑在一个类中,在FP中,您将与关联的操作分开定义数据结构.这意味着FP方法可以更轻松地定义数据的新操作,而OO方法可以更轻松地向数据结构添加新信息.就个人而言,我发现自己定义新的操作比添加新的领域和FP风格的套装要好得多.

与Haskell中Java示例最接近的类似是定义类型类 -

data Month = January | February | March | April
           | May | June | July | August |September
           | October | November |December
  deriving (Eq, Ord, Show, Read, Bounded, Enum)

data Year = Int

class HasDays X where
  maxdays :: X -> Int
  days    :: X -> Year -> Int
  -- Any other "methods" here

instance HasDays Month where
  maxdays January = 31
  maxdays February = 29
  maxdays .. = .. -- Similar code for other months

  days February y = .. -- Leap year calculation
  days m _ = maxdays m
Run Code Online (Sandbox Code Playgroud)