[haskell] Haskell 기능을 최대한 짧게하려면 어떻게해야합니까?

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



답변

다음과 Month같은 인스턴스 를 만들었으므로 가드를 사용할 수 있습니다 Ord.

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


답변

Enum두 데이터 유형 정의 deriving절 에 모두 추가 한 다음

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

3 월부터 봄에 시즌 3 개월, 1 년에 4 계절.


답변

이것은 가독성을 위해 약간의 조정만으로 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여러 방정식 대신-문을 사용하여 작성시 반복성을 다소 줄일 수 있습니다 .


답변