2012-01-03 34 views
14

Tengo un programa haskell para listar todos los enteros de [1..n] basados ​​en la entrada n. Quiero filtrar ciertos números basados ​​en una condición y mostrarlos como una lista. ¿dónde y cómo puedo usar la función/condición del filtro?¿Cómo uso la función de filtro en Haskell?

Según la documentación Haskell:

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

filtro, aplicado a un predicado y una lista, devuelve la lista de aquellos elementos que satisfacen el predicado; es decir,

filter p xs = [ x | x <- xs, p x] 

Respuesta

21

Ya lo tienes, más o menos. Entonces, el resto del trato es diseñar la función de predicado para su lista. Suponiendo que ya tiene una lista llamada xs y una función de predicado p, todo lo que tendría que hacer es

filter p xs.

A menudo, verá p se define como un anónimo, o lambda, expresión, así:

filtro (\ n -> n `mod` 2 == 0) x.

No es necesario, y puede ser útil como principiante para definir las funciones nombradas.

ISEVEN n = n `mod` 2 == 0

evenListNumbers xs = Filtro ISEVEN xs

evenListNumbers [1,2,3,4]

Cuál es este [2,4].

Así que una función de predicado para un filtro de lista dado toma un elemento de lista y devuelve un valor booleano. Si es verdadero, el elemento se conserva (o se agrega a la lista resultante), y si es falso, se pasa por alto.

+0

gracias! lo explicó muy claramente. Entendí cómo filtrar los números pares e impares, pero ¿qué pasa con el filtrado de los números que pueden dividir la entrada n? algo así como isDivisible n = filter [1..n] div n? ¿cuál es la sintaxis para eso?: S – Amjad

+0

Tendría que hacer una función en la línea de: 'isDivisible n p = n \' mod \ 'p == 0' y usar eso como su predicado. Tenga en cuenta que esta función devuelve verdadero si el resto de la división de n con p es cero, y de lo contrario es falso. Tenga en cuenta que los argumentos ahora están en un orden ligeramente diferente de lo que desea, por lo que es posible que desee simplemente voltearlos en la definición por ahora, o use 'flip'. – Sarah

+0

Obteniendo errores, no estoy seguro de dónde definir este predicado. Creo que no puedo usarlo en la misma línea que filtro ¿verdad? Quiero que el programa obtenga una entrada y enumere todos sus divisores. quiero saber cómo se define el predicado para esto. Gracias. – Amjad

2

Bueno, transformar esa condición en un predicado (una función que devuelve Bool) y lo utilizan para filtrar los números.

Por ejemplo, si usted tiene que seleccionar sólo los números impares se puede utilizar filter odd [1..n]

+0

Quiere decir que tengo que definir el predicado que se utilizará con filtro y es una función Int -> Bool que se pasa como primer argumento para filtrar. ¿cómo exactamente puedo hacer esto? esa es mi pregunta. por ejemplo: cómo enumero todos los divisores de un entero que ingresé. – Amjad

+0

Sí, necesita una función de tipo 'Int -> Bool'. Su segundo ejemplo con listados de divisores de números de entrada no puede funcionar de esta manera. Porque de un solo número obtienes una lista de divisores, por lo tanto tu función tendrá el tipo 'Int -> [Int]' que no es lo mismo que 'Int -> Bool'. En este caso, tal vez 'map' o' concatMap' es lo que deseas. –