J'ai récemment rencontré des situations où je dois passer une fonction de prédicat à une autre fonction, et bien souvent la logique que je recherche est essentiellement "cette valeur correspond-elle à ce modèle?"
La correspondance de modèle semble être préférée dans les déclarations, les do
blocs et les listes de compréhension, mais il existe un certain nombre de fonctions qui prennent un prédicat a -> Bool
, où il serait très pratique de passer en quelque sorte un modèle. Par exemple, takeWhile
, until
, find
, span
, etc.
Jusqu'à présent, j'ai fait \a -> case a of MyCons _ -> True; otherwise -> False
ou écrit une fonction nommée à la fois, let myPred (MyCons _) = True; myPred _ = False in
mais elles semblent toutes les deux terriblement laides et pas très idiomatiques. La façon "évidente" (et erronée) serait quelque chose comme \(MyCons _) -> True
ça, mais cela jette une erreur pour être partiel, naturellement, et même alors, il semble qu'il doit y avoir une manière plus propre.
Existe-t-il une manière plus succincte / propre de faire ce genre de choses? Ou est-ce que je vais tout à fait mal?
let myPred...
style est mauvais , mais il semble beaucoup plus verbeux que ce à quoi je m'attendais pour une idée très simple, ce qui m'amène à me demander si j'aboie le mauvais arbre.
maybe :: b -> (a -> b) -> Maybe a -> b
et bool :: a -> a -> Bool -> a
, puis à l'utiliser avec des fonctions de production booléennes comme argument (s). par exemple myCons z f (MyCons x) = f x ; myCons z f _ = z
, puis appelez myCons False (const True) aMyConsValue
. c'est presque ce que vous avez écrit, il y a juste un niveau supplémentaire "d'indirection" / "abstraction" via des arguments fonctionnels, incorporés dans celui-ci.
let
clause que vous n'aimez pas - bien que je préfère lawhere
clause équivalente afin que cela n'encombre pas la définition principale. Bien sûr, si vous finissez par avoir besoin de cet utilitaire plus d'une fois, vous le définirez comme une fonction de niveau supérieur.