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 doblocs 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 -> Falseou écrit une fonction nommée à la fois, let myPred (MyCons _) = True; myPred _ = False inmais 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 -> bet 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.
letclause que vous n'aimez pas - bien que je préfère lawhereclause é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.