3

LYAH派生インスタンスで次のように述べています

[...]すべての値コンストラクターはnullary(パラメーター、つまりフィールドを取りません)であるため、列挙型クラスの一部にすることができます。

data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
deriving (Eq, Ord, Show, Read, Bounded, Enum)

今、私が数ヶ月かかると、それは

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

私の質問は次のとおりです。

  1. 各月の最大日数の値をどこに保存しますか?
  2. うるう年の場合は2月の場合、2月のmaxDaysは29日であり、それ以外の場合は28日になります。

Javaでは、次のようにコーディングできます。

public enum Month {  
    January (31),  
    February (29),  
    March (31),  
    April (30),  
    May (31),  
    June (30),  
    July (31),  
    August (31),  
    September (30),           
    October (31),  
    November (30),  
    December (31),  
    ;  
    private int maxDays; // instance variables  
    private (int maxDays) { // constructors always private  
           this.maxDays = maxDays;  
    }  
    Public int getMaxDays () {  
       return maxDays;  
    }
4

2 に答える 2

7

なぜMonth列挙型である必要があるのですか?コードに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
于 2012-07-26T06:40:23.990 に答える
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
于 2012-07-26T04:03:43.940 に答える