Home > Net >  How can I put multiple elements into ‘elem’
How can I put multiple elements into ‘elem’

Time:02-11

Let’s say I want to do something like"ace" `elem` "abcdefg". Of course we can’t because you need a list of the first elements type. Instead is there a way we could turn this into taking every char in "ace" and comparing them individually with "abcdefg", then using or statements to combine them, but without manually doing this (because in my program it’s a variable of unknown length and characters).

CodePudding user response:

This is a specific case of a more general problem: you have a function Char -> Bool (or a -> Bool) and you want to adapt it as a function [a] -> Bool. In other words, what you need is a function

adaptOr :: (a -> Bool) -> ([a] -> Bool)

Well, that's actually something you can ask Hoogle about! The first hits are

any :: (a -> Bool) -> [a] -> Bool
base GHC.List GHC.OldList
Applied to a predicate and a list, any determines if any element of the list satisfies the predicate. For the result to be False, the list must be finite; True, however, results from a True value for the predicate applied to an element at a finite index of a finite or infinite list.

>>> any (> 3) []
False

>>> any (> 3) [1,2]
False

>>> any (> 3) [1,2,3,4,5]
True

>>> any (> 3) [1..]
True

>>> any (> 3) [0, -1..]
* Hangs forever *

all :: (a -> Bool) -> [a] -> Bool
base GHC.List GHC.OldList
Applied to a predicate and a list, all determines if all elements of the list satisfy the predicate. For the result to be True, the list must be finite; False, however, results from a False value for the predicate applied to an element at a finite index of a finite or infinite list.

>>> all (> 3) []
True

>>> all (> 3) [1,2]
False

>>> all (> 3) [1,2,3,4,5]
False

>>> all (> 3) [1..]
False

>>> all (> 3) [4..]
* Hangs forever *

Now you need to think which of these is right for your case, and then use it accordingly. You want

  all⁄any (\c -> c`elem`"abcdefg") "ace"

This can also be written with an infix section:

  all⁄any (`elem`"abcdefg") "ace"

CodePudding user response:

Here's using that or statement as you wanted:

or [c `elem` "abcdefg" | c <- "ace"]

How to come up with this?

You already know that you want

  'a' `elem` "abcdefg" ||
  'c' `elem` "abcdefg" ||
  'e' `elem` "abcdefg"

and the type of (||) is Bool -> Bool -> Bool.

But you have a list of the characters to test. And after you've tested each of them, you'll have the list of Boolean results. Thus you want a function of type [Bool] -> Bool.

Hoogle time!

  • Related