I've recently been running into situations where I need to pass a predicate function into another function, and quite often the logic I am looking for is essentially "does this value match this pattern?"
Pattern matching seems to be preferred in declarations, do
blocks, and list comprehensions, but there are a number of functions that take a predicate a -> Bool
, where it would be very handy to somehow pass in a pattern. For example, takeWhile
, until
, find
, span
, etc.
Thus far I've been doing \a -> case a of MyCons _ -> True; otherwise -> False
, or writing a named function a la let myPred (MyCons _) = True; myPred _ = False in
but they both seem terribly ugly and not very idiomatic. The "obvious" (and wrong) way would be something like \(MyCons _) -> True
but that throws an error for being partial, naturally, and even then it feels like there must be a cleaner way.
Is there a more succinct / clean way to do this sort of thing? Or am I going about things entirely the wrong way?
In mathematics, a predicate is either a relation or the boolean-valued function that amounts to the characteristic function or the indicator function of such a relation. A function P: X→ {true, false} is called a predicate on X. When P is a predicate on X, we sometimes say P is a property of X.
Just to simplify things . predicate is a function that return a true or false value based on some condition. it's used as a "filter criteria" meaning lets consider an array of numbers and a predicate that returns true if number > 0 , false other wise . filter is a function that returns a new array based on a predicate ( or a "filter criteria". )
Predicates are used in higher order functions, applied to a given function (a.k.a transformer) element-wise to a list of elements and returns a list of results. Transformer is a function applies to each element and will produce one or more new elements.
asPredicate () method of a Pattern class used to creates a predicate object which can be used to match a string.Predicate is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference. Parameters: This method accepts nothing as parameter.
You can use the Language Extension LambdaCase to use \case MyCons _ -> True; _ -> False
, although this doesn't save that many characters.
I believe you could write a series of functions constructedWith :: (Generic a) => (b -> a) -> a -> Bool
, constructedWith2 :: (Generic a) => (b -> c -> a) -> a -> Bool
, but I'm not competent enough with Generics to implement it without a few hours testing things out. I will try this, and edit my answer if I can figure it out, or if it is a dead end.
EDIT: Yes, you can do it! Here's a link to my code, which implements it all from scratch:
https://repl.it/@lalaithion/ConstructedWith
However, using something like http://hackage.haskell.org/package/generic-deriving-1.13.1/docs/Generics-Deriving-ConNames.html for all of the generic code plumbing might be better.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With