2011-06-03 8 views
6

Estoy tratando de jugar con el equivalente de haskell del 'Scala One Liners' que recientemente apareció en Reddit/Hacker News.¿Cómo verificar si algunos elementos están en una lista?

Esto es lo que tengo hasta ahora (la gente probablemente ellos podrían hacer mucho mejor que yo, pero estos son mis intentos de nivel principiante)

https://gist.github.com/1005383

el que estoy atascado en esta verificando si los artículos están en una lista. Básicamente, el ejemplo de Scala es este

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(_))) 

Estoy un poco perplejo sobre cómo hacer esto en Haskell. Sé que usted puede hacer:

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

Para verificar si uno de las palabras está presente, pero el ejemplo Scala pregunta si alguna de las palabras en la lista de palabras están presentes en la cadena de prueba.

Parece que no puedo encontrar una función contains o algo similar a eso. Sé que probablemente puedas escribir una función para hacerlo, pero eso frustra el punto de hacer esta tarea en una línea.

Cualquier ayuda sería apreciada.

Respuesta

11

Puede usar la función elem del Preludio, que comprueba si un elemento está en una lista. Se utiliza comúnmente en forma infija:

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

A continuación, puede utilizarlo en una sección operador igual que lo hizo con ==:

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 

Cuando ves que necesitas una función, pero no conoce el nombre, intente usar Hoogle para buscar una función por tipo.

Aquí quería algo que compruebe si algo de cualquier tipo está en una lista de cosas del mismo tipo, es decir, algo así como a -> [a] -> Bool (también necesita una restricción Eq, pero digamos que no sabía ese). Al escribir este tipo de firma en Hoogle gives you elem as the top result.

+0

Perfecto, gracias! – djhworld

6

¿Qué le parece usar Data.List.intersect?

import Data.List.intersect 

not $ null $ intersect (words tweet) wordList 
3

Aunque ya hay buenas respuestas que pensé que sería bueno escribir algo en el espíritu de su código original mediante any. De esta manera se llega a ver cómo componer sus propias consultas complejas a partir de partes reutilizables simples en lugar de utilizar partes off-the-shelf como intersect y elem:

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

Con un poco de reordenamiento se puede ordenar de leerlo en Inglés : ¿hay alguna palabra x en la oración tal que haya y en la lista tal que x == y? Está claro cómo extender a más 'ejes' que dos, realizar comparaciones que no sean ==, e incluso mezclarlo con all.

Cuestiones relacionadas