Haskellの機能を可能な限り短くするにはどうすればよいですか?


12

seasonこの関数は代数関数を使用していますが、コードを繰り返しているような気がします。

できるだけ短くするにはどうすればよいですか?

data Month = Jan | Feb | Mar | Apr | May | June | July | Aug | Sept| Oct | Nov | Dec
     deriving (Eq,Ord,Show,Read)

data Seasons = Spring | Summer | Autumn | Winter
     deriving (Eq,Ord,Show,Read)

season :: Month -> Seasons
season Jan = Winter
season Feb = Winter
season Mar = Spring
season Apr = Spring
season May = Spring
season June = Summer
season July = Summer
season Aug = Summer
season Sept = Autumn
season Oct = Autumn
season Nov = Autumn
season Dec = Winter

関数とコンストラクターの名前を1文字に変更すると、%短縮されます)
luqui

回答:


20

次のMonthインスタンスを作成したので、ガードを利用できますOrd

season :: Month -> Seasons
season m | m <= Feb = Winter
         | m <= May = Spring
         | m <= Aug = Summer
         | m <= Nov = Autumn
         | otherwise = Winter

11

Enum両方のデータ型定義のderiving句に追加してから、

season :: Month -> Seasons
season m  =  toEnum ((fromEnum m - 2) `div` 3 `mod` 4)

シーズンは3か月、年は4シーズン、春は3月から始まります。


7

これは、Will Nessの回答Enumインスタンスを介して月のインデックスを計算する)と非常によく似ていますが、読みやすさのためにいくつかの調整を加えています。

data Month = Jan | Feb | Mar | Apr | May | June | July | Aug | Sept | Oct | Nov | Dec
     deriving (Eq, Ord, Show, Read, Enum)

data Season = Spring | Summer | Autumn | Winter
     deriving (Eq, Ord, Show, Read, Enum)

season :: Month -> Season
season = toEnum . (`div` 3) . monthIndexStartingFrom Mar
    where
    monthIndexStartingFrom :: Month -> Month -> Int
    monthIndexStartingFrom base month = (fromEnum month - fromEnum base) `mod` 12

いずれにせよ、その単純さのために、すべてのケースを明示的にリストしている元のソリューションをサポートするために何か言いたいことがあります。case複数の方程式の代わりに-ステートメントを使用することで、それを書く際の反復性をいくらか減らすことができます。


1
ここの投票パターンに戸惑っています。:) OPは可能な限り短いコードを要求します。しかたがない。:)
Will Ness
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.