djhworld
djhworld

Reputation: 6776

How to verify if some items are in a list?

I'm trying to mess about trying the haskell equivalent of the 'Scala One Liners' thing that has recently popped up on Reddit/Hacker News.

Here's what I've got so far (people could probably do them a lot better than me but these are my beginner level attempts)

https://gist.github.com/1005383

The one I'm stuck on is verifying if items are in a list. Basically the Scala example is this

val wordlist = List("scala", "akka", "play framework", "sbt", "typesafe")
val tweet = "This is an example tweet talking about scala and sbt."
(words.foldLeft(false)( _ || tweet.contains(_) ))

I'm a bit stumped how to do this in Haskell. I know you can do:

any (=="haskell") $ words "haskell is great!"

To verify if one of the words is present, but the Scala example asks if any of the words in the wordlist are present in the test string.

I can't seem to find a contains function or something similar to that. I know you could probably write a function to do it but that defeats the point of doing this task in one line.

Any help would be appreciated.

Upvotes: 6

Views: 315

Answers (3)

Dan Piponi
Dan Piponi

Reputation: 8116

Although there are already good answers I thought it'd be nice to write something in the spirit of your original code using any. That way you get to see how to compose your own complex queries from simple reusable parts rather than using off-the-shelf parts like intersect and elem:

any (\x -> any (\y -> (y == x)) $ words "haskell is great!")
    ["scala", "is", "tolerable"]

With a little reordering you can sort of read it in English: is there any word x in the sentence such that there is any y in the list such that x == y? It's clear how to extend to more 'axes' than two, perform comparisons other than ==, and even mix it up with all.

Upvotes: 3

nimrodm
nimrodm

Reputation: 23779

How about using Data.List.intersect?

import Data.List.intersect

not $ null $ intersect (words tweet) wordList

Upvotes: 6

hammar
hammar

Reputation: 139830

You can use the elem function from the Prelude which checks if an item is in a list. It is commonly used in infix form:

Prelude> "foo" `elem` ["foo", "bar", "baz"]
True

You can then use it in an operator section just like you did with ==:

Prelude> let wordList = ["scala", "akka", "play framework", "sbt", "types"]
Prelude> let tweet = "This is an example tweet talking about scala and sbt."
Prelude> any (`elem` wordList) $ words tweet
True

When you find yourself needing a function, but you don't know the name, try using Hoogle to search for a function by type.

Here you wanted something that checks if a thing of any type is in a list of things of the same type, i.e. something of a type like a -> [a] -> Bool (you also need an Eq constraint, but let's say you didn't know that). Typing this type signature into Hoogle gives you elem as the top result.

Upvotes: 11

Related Questions