2012-10-06 49 views
7

¿Cómo se mapea una función para operar en listas dentro de una lista? Lo siguiente es justo lo que trato de hacer como ejemplo, pero solo estaba haciendo una pregunta general. ¡Gracias por adelantado!Haskell: Asignar la función a una lista de listas

En este momento, estoy tratando de asignar una función, cambiar, en cada lista de una lista (devuelta por itrCol xs).

evalChange xs = map change $ itrCol xs 

donde itrCol devuelve una lista de listas, donde cada lista contiene una columna.

itrCol xs = [getCol x xs | x <- (take (width xs) (iterate (\x -> (x + 1)*1) 0))] 

columna listas getCol lista dada de índices de columna

getCol :: Int -> [t] -> [t] 

y el cambio es:

change []  = [] 
change [x] = [x] 
change [x,y] = [x,y] 
change (x:y:z:ws) | x == y && y == z = 0 : y*(-1) : 0 : change ws 
change (x:xs) = x : change xs 
+0

No se olvide de aceptar una respuesta a su pregunta =) (haciendo clic en el icono de verificación verde en la respuesta) –

+0

¿El código que enlistó aquí le da algún mensaje de error? Si es así, ¿Que son? Si no, ¿qué preguntas exactamente? El único error que veo es que usaste 'ancho' cuando podrías haber querido decir' longitud'? –

Respuesta

6

posible que utilices currying y otra llamada al mapa.

map (map change) $ itrCol xs 

Para obtener más información sobre currying echar un vistazo a que chapter in Learn You A Haskell, un gran libro principiante en Haskell.

+0

¡Gracias por su respuesta! Soy nuevo en currying, pero a partir de mi investigación, ¿está cambiando el número de argumentos que toma una función? – user1670032

+0

La mejor explicación que he leído es [Learn You A Haskell] (http://learnyouahaskell.com/higher-order-functions#curried-functions). ¡Deberías leer este libro entero, no encontrarás nada mejor! –

+1

¡Gracias! Este es mi primer lenguaje de programación funcional, y es bastante diferente de los lenguajes imperativos a los que estoy acostumbrado. Definitivamente voy a mirar esto! – user1670032

2

map (y fmap más importante) esencialmente levanta una función para trabajar en las listas, que le da una nueva función: (I añade parens superfluos para que sea más clara)

map :: (a -> b) -> ([a] -> [b]) 

Si asigna esa segunda función ([a] -> [b]) obtendrá una función que trabaja en las listas de listas:

evalChange xs = map (map change) $ itrCol xs 

(si esto no es lo que quería, por favor, aclarar)

+0

¡Gracias por su respuesta! Por alguna razón, esto me da un error. Traté de incluir el tipo de función para el mapa, pero aún así me da un error. No estoy seguro de cómo copiar ese error en GHC aquí? – user1670032

+0

@ user1670032 copiar y pegar como una edición de su respuesta. Si no sabes cómo, haz una captura de pantalla. – Pubby

+2

@ user1670032 Si está utilizando ghci en Windows, debe hacer clic en el icono en la esquina superior izquierda y luego seleccionar "Editar -> Marcar" en el menú. Ahora resalta lo que deseas copiar y luego presiona Enter. A partir de ahí, solo pegue como siempre que lo desee. –

11

¡Mira esto!

map   :: (a -> b) -> [a] -> [b] 
(map.map)  :: (a -> b) -> [[a]] -> [[b]] 
(map.map.map) :: (a -> b) -> [[[a]]] -> [[[b]]] 

etc.

+0

@AndrewC, sí, esta no es una respuesta pedagógicamente útil y probablemente no me gustaría mucho si no la hubiera escrito ... – luqui

1

El tipo de firma de map es:

map :: (a -> b) -> [a] -> [b] 

Una firma de tipo sensata para change es:

change :: [Integer] -> [Integer] 

Ahora map espera una función de a a b como su primer argumento. Si le damos change, una función de [Integer] a [Integer], luego a = [Integer] y b = [Integer].

map change :: [[Integer]] -> [[Integer]] 

Ahora bien, si esa lista la comprensión producido a partir de iterCol xs suministra una [[Integer]], entonces podemos aplicar eso a map change:

map change (itrCol xs) :: [[Integer]] 

Todo esto se ve muy bien a mí. Funciona porque map es polimórfico.Si le asigna una función que convierte A en B, le devolverá una función que convierte listas de A en listas de B. No importa lo que sean A y B: como puede ver aquí, ¡incluso pueden ser listas!