Comment rendre ma fonction Haskell aussi courte que possible?

12

La seasonfonction utilise des fonctions algébriques mais j'ai l'impression que le code est répétitif.

Comment le rendre aussi court que possible?

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
la source
Renommer votre fonction et vos constructeurs en lettres simples raccourcirait le%)
luqui

Réponses:

20

Vous pouvez utiliser des gardes, car vous avez créé Monthune instance de Ord:

season :: Month -> Seasons
season m | m <= Feb = Winter
         | m <= May = Spring
         | m <= Aug = Summer
         | m <= Nov = Autumn
         | otherwise = Winter
Willem Van Onsem
la source
11

Ajoutez Enumaux deux derivingclauses de vos définitions de types de données, puis

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

Trois mois dans une saison, quatre saisons dans une année, le printemps commençant en mars.

Will Ness
la source
7

Ceci est très similaire à la réponse de Will Ness (faire de l'arithmétique sur les indices mensuels via des Enuminstances), mais avec quelques ajustements pour plus de lisibilité:

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

Dans tous les cas, il y a quelque chose à dire à l'appui de votre solution d'origine répertoriant tous les cas de manière explicite, pour sa simplicité. La répétitivité de l'écriture peut être quelque peu réduite en utilisant une casedéclaration au lieu de plusieurs équations.

duplode
la source
1
Je suis perdu avec les schémas de vote ici. :) l'OP demande le code le plus court possible. tant pis. :)
Will Ness