Як зробити свою функцію 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)

Три місяці в сезоні, чотири сезони на рік, весна починається з березня.


7

Це дуже схоже на відповідь Вілла Несса (роблячи арифметику за місячними індексами через 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
Я в збитку з приводу цього режиму голосування. :) ОП запитує найкоротший можливий код. Ну добре. :)
Буде Несс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.