Jak sprawić, by moja funkcja Haskell była jak najkrótsza?

12

seasonFunkcja używa funkcji algebraicznych ale czuję, że kod jest powtarzalne.

Jak mogę to zrobić tak krótko, jak to możliwe?

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
Stephen Adams
źródło
Zmiana nazwy funkcji i konstruktorów na pojedyncze litery skróciłaby ją o%)
luqui

Odpowiedzi:

20

Możesz skorzystać ze strażników, ponieważ wykonałeś Monthinstancję Ord:

season :: Month -> Seasons
season m | m <= Feb = Winter
         | m <= May = Spring
         | m <= Aug = Summer
         | m <= Nov = Autumn
         | otherwise = Winter
Willem Van Onsem
źródło
11

Następnie dodaj Enumdo obu definicji definicji typu danychderiving

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

Trzy miesiące w sezonie, cztery pory roku, wiosna od marca.

Will Ness
źródło
7

Jest to bardzo podobne do odpowiedzi Willa Nessa (wykonywanie arytmetyki na indeksach miesięcznych poprzez Enuminstancje), z kilkoma drobnymi poprawkami ze względu na czytelność:

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

W każdym razie jest coś, co można powiedzieć na poparcie twojego oryginalnego rozwiązania, wymieniając wszystkie przypadki wyraźnie, ze względu na jego prostotę. Powtarzalność w pisaniu może być nieco zmniejszona poprzez użycie case-statement zamiast wielu równań.

duplode
źródło
1
Brakuje mi tutaj schematów głosowania. :) OP prosi o możliwie najkrótszy kod. No cóż. :)
Czy Ness