2010-05-08 16 views
10

Un problema común que tengo en Haskell es extraer todos los términos en una lista que pertenece a un constructor de datos específico y me pregunto si hay formas mejores que las camino lo estoy haciendo en este momento.Cómo extraer términos de un constructor de datos específico de una lista en Haskell

Digamos que tienes

data Foo = Bar | Goo 

, la lista

foos = [Bar, Goo, Bar, Bar, Goo] 

y desea extraer todos los Goo s de foos. En este momento usualmente hago algo como

goos = [Goo | Goo <- foos] 

y todo está bien. El problema es cuando Goo tiene un montón de campos y me veo obligado a escribir algo como

goos = [Goo a b c d e f | Goo a b c d e f <- foos] 

que está lejos de ser ideal. ¿Cómo manejas generalmente este problema?

Respuesta

20

parece que hay dos partes a esta pregunta:

  1. ¿Existe una manera más fácil de hacer la coincidencia de patrones
  2. son listas por comprensión bien aquí?

En primer lugar, no es una mejor manera para que coincida en campos que no se preocupan por:

goos = [ x | [email protected](Goo {}) <- foos] 

En segundo lugar, el uso de listas por comprensión es una forma perfectamente cromulent de escribir este tipo de filtros. Por ejemplo, en la biblioteca de base, catMaybes se define como:

catMaybes :: [Maybe a] -> [a] 
catMaybes ls = [x | Just x <- ls] 

(de la biblioteca de base). Entonces ese modismo está bien.

+0

Pero OP quiere algo similar a '[Just x | Solo x <- ls] ', no' catMaybes' o 'derechos'. – kennytm

+0

Está bien, la pregunta está en dos partes: si la lista de comprensiones está bien, y en segundo lugar, qué forma de coincidencia de patrones. Lo aclararé –

4

Usted podría utilizar

[x | [email protected](Goo _ _ _ _ _ _) <- foos] 

También puede definir un

isGoo :: Foo -> Bool 
isGoo (Goo _ _ _ _ _ _) = True 
isGoo _ = False 

y luego usar filter

filter isGoo foos 

o

[x | x <- foos, isGoo] 
Cuestiones relacionadas