Imaginez que vous avez une note comme
Rating = OneStar | TwoStars | ThreeStars | FourStars | FiveStars
4 Réponses :
Le meilleur moyen serait de simplement ajouter Étant donné que vous avez répertorié vos constructeurs en ordre croissant, l'instance Dérive Toutefois, si la modification de la commande dans la définition n'est pas une option pour une raison quelconque, vous pouvez toujours dériver l'équation, car pour que l'ordre n'a pas d'importance. Compte tenu d'une instance d'équation, nous pouvons écrire manuellement une instance pour ORD. La manière la plus succincte de définir la comparaison serait probablement d'épeler toutes les combinaisons pour lesquelles la comparaison devrait renvoyer lt, puis utiliser simplement comparer x y | x == Y = EQ; Comparez _ _ = GT pour les combinaisons restantes. P> dérivé (eq, ord) code> à la définition du type. p>
ORD code> vous donnera exactement la commande souhaitée. P>
Merci, je ne savais pas que la commande est préservée.
Question bonus: Que se passe-t-il si la commande dans le Définiton ne refléterait pas l'ordre numérique?
@Lenny: Ensuite, vous auriez instancier ORD et définir comparer code> à la main (en supposant que la modification de la commande dans la définition n'est pas une option pour une raison quelconque) - Vous pouvez toujours dériver l'équation possible car pour que le L'ordre n'a pas d'importance. Le moyen le plus succinct de définir comparer code> serait probablement d'épeler toutes les combinaisons pour lesquelles la comparaison doit renvoyer lt, puis utiliser simplement comparer x y | x == Y = EQ; Comparez _ _ = gt code> pour les combinaisons restantes.
@Lenny Solution plus facile: changez la définition de sorte qu'il s'agit d'une commande ascendante!
@Lenny pour certains protocoles Travail J'ai même ajouté des espaces réservés non utilisés: Data X = VAL0 | Val1 | Val2 | Inutilisé3 | Inutilisé4 | VAL5 code>. Idiot, est juste parfois le moyen le plus rapide et le plus simple d'aller (mais pas si vous avez de grandes lacunes, évidemment).
Comme cela n'a été mentionné, vous pouvez dériver eq code> et ord code>. Ou vous pouvez dériver enum code> et ensuite faire instance Eq Rating where
OneStar == OneStar = True
TwoStar == TwoStar = True
...
_ == _ = False
Pour quiconque se demande, voici la mise en œuvre complète, explicite et de la chaudière:
Utilisation de chiffres romains.
Utilisation de case code> pour la facilité de lecture. P>
Merci beaucoup! Cela m'a pris pour toujours pour trouver un exemple de châssis entièrement écrit!
Un autre moyen d'implémenter Comparer code> est de tomber sur un type qui est déjà une instance de ord code>. data Rating = OneStar | TwoStars | ThreeStars | FourStars | FiveStars
deriving (Show, Eq)
instance Ord Rating where
compare x y = compare (r2n x) (r2n y)
where
r2n OneStar = 1
r2n TwoStars = 2
r2n ThreeStars = 3
r2n FourStars = 4
r2n FiveStars = 5