Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a convenient way to use a pattern as a predicate function?

Tags:

haskell

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?

like image 269
David Sampson Avatar asked Jan 07 '20 23:01

David Sampson


People also ask

What is a predicate in math?

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.

What is the difference between a predicate and a filter?

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". )

What is the difference between predicates and Transformers?

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.

How do you match a string with a predicate in Python?

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.


Video Answer


1 Answers

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.

like image 144
Izaak Weiss Avatar answered Oct 08 '22 18:10

Izaak Weiss