开发者

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.


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.


How about using Data.List.intersect?

import Data.List.intersect

not $ null $ intersect (words tweet) wordList


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜