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

함수와 생성자를 단일 문자로 이름을 바꾸면 단축됩니다 %)
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 월부터 봄에 시즌 3 개월, 1 년에 4 계절.


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.