Je cherche un moyen de simplifier les modèles de fonction lorsque les données réelles ne sont pas nécessaires:
data X = A | B String | C Int Int String
myfn :: X -> Int
myfn A = 50
myfn (B _) = 200
myfn (C _ _ _) = 500
Existe-t-il un moyen de créer un modèle plus simple pour faire correspondre C, en rejetant simplement les valeurs?
hsdev ajoute un conseil "Conseil: utilisez des modèles d'enregistrement", mais Google ne m'a pas aidé là-bas.
Vous pouvez utiliser des modèles d'enregistrement comme celui-ci:
data X = A | B {name :: String} | C {x::Int, y::Int, name::String}
myfn :: X -> Int
myfn A = 50
myfn B{} = 200
myfn C{} = 500
Les modèles d'enregistrement vous permettent de donner des noms aux champs des constructeurs. vous pouvez également faire des choses comme:
myfn C{name=n} = length n
vous pouvez donc voir que vous ne pouvez faire correspondre les motifs que sur le champ spécifique dont vous avez besoin.
Remarque: vous pouvez utiliser le modèle d'enregistrement vide même avec des types de données qui n'utilisent pas la syntaxe d'enregistrement:
data A = A Int | B Int Int
myfn A{} = 1
myfn B{} = 2
C'est bon. Il existe un certain nombre d'autres extensions liées aux modèles d'enregistrement:
RecordWildCards
vous permet d'écrire des choses comme C{..}
qui est équivalent au motif: C{x=x, y=y, name=name}
, c'est-à-dire qu'il correspond à tous les champs et vous avez maintenant dans la portée x
avec la valeur correspondant au champ x
etc.
NamedFieldPuns
vous permet d'écrire C{name}
pour être équivalent à C{name=name}
, de sorte que name
est désormais dans la portée et contient la valeur correspondant au champ name
.
Gardez à l'esprit que l'utilisation de modèles d'enregistrement ne vous empêche pas d'utiliser vos constructeurs de manière positionnelle, vous pouvez donc toujours écrire:
myfn (B _) = 200
Seul ajoute des fonctionnalités.