2012-09-09 6 views
5

Data.Array no proporciona pliegues para el tipo Array. (Ch. 12)¿Por qué Haskell no proporciona pliegues para arrays unidimensionales?

En Real World Haskell, la razón se dice que es que Array s podrían ser plegados de diferentes maneras en base a las necesidades del programador:

En primer lugar, hay varios tipos de pliegues que tienen sentido. Es posible que aún deseemos plegar elementos individuales, pero ahora también tenemos la posibilidad de plegar filas o columnas. Además de esto, para el plegado elemento a elemento, ya no existen solo dos secuencias para el cruce.

¿No es exactamente así de List s? Es muy común representar, p. una matriz con un List multidimensional, pero todavía hay pliegues definidos para unidimensional List s.

¿Cuál es la sutileza me falta? ¿Es que un Array multidimensional es suficientemente diferente de un Array de Array s?

Editar: Hm, incluso multidimensionales matrices ¿Tiene pliegues definido, en forma de casos de Data.Foldable [0] Entonces, ¿cómo encaja eso con el mundo real Haskell cita.?

[0] http://hackage.haskell.org/packages/archive/base/4.6.0.0/doc/html/Data-Foldable.html

+0

La diferencia entre las matrices multidimensionales y las listas anidadas es que todas las matrices tienen esencialmente el mismo tipo: 'Array Int e',' Array (Int, Int) e', 'Array (Int, Int, Int) e' .... Por lo tanto, no puede realizar una función que solo esté definida para matrices unidimensionales, mientras que 'foldr' toma una lista de listas y la procesa lista por lista, en lugar de concatenar todas las listas y procesarla elemento por elemento. –

Respuesta

8

Ya que mencionas la diferencia entre un "multidimensional" Array y un Array de Array s, que ilustrará el punto muy bien, junto con una comparación con las listas.

Un pliegue (en el sentido de clase Foldable) es una operación inherentemente lineal, al igual que las listas son una estructura intrínsecamente lineal; un doblez derecho caracteriza completamente una lista al hacer coincidir sus constructores uno a uno con los argumentos al foldr.Si bien puede definir funciones como foldl también, hay una opción clara de un doblez canónico estándar.

Array no tiene una estructura transparente tal que se pueda combinar uno a uno en un pliegue. Es un tipo abstracto, con acceso a elementos individuales proporcionados por valores de índice, que puede ser de cualquier tipo que tenga una instancia Ix. Entonces, no solo no existe una opción obvia para implementar un pliegue, tampoco existe una estructura lineal intrínseca. Ocurre que Ix le permite enumerar un rango de índices, pero esto es más un detalle de implementación que cualquier otra cosa.

¿Qué hay de Array s multidimensional? Realmente no existen, como tal. Ix define instancias para tuplas de tipos que también son instancias, y si desea pensar en tales tuplas como un tipo de índice para un Array "multidimensional", ¡adelante! Pero todavía son solo tuplas. Obviamente, Ix pone un orden lineal en esas tuplas, pero ¿qué es? ¿Puedes encontrar algo en la documentación que te lo diga?

Por lo tanto, creo que podemos decir con seguridad que el plegado de una Array multidimensional utilizando el orden definido por Ix es prudente a menos que realmente no importa qué orden a obtener los elementos en.

Para una Array de Array s , por otro lado, solo hay una manera sensata de combinarlos, al igual que las listas anidadas: pliegue cada Array interior por separado de acuerdo con su propio orden de elementos, luego doble el resultado de cada uno según el orden de los elementos externos Array.


Ahora, se podría objetar razonablemente que ya no hay distinción de tipos entre unidimensional y multidimensional Array s, y el primero se puede suponer que tienen un ordenamiento veces sensato basado en la Ix ejemplo, ¿por qué no usar ese orden por defecto? Ya hay una función que devuelve los elementos de Array en una lista, después de todo.

Como resultado, la biblioteca en sí estaría de acuerdo con usted, porque eso es exactamente lo que hace la instancia Foldable.

4

hay una manera natural para doblar las listas, que es foldr. Tenga en cuenta los tipos de los constructores de la lista:

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

Sustitución de las ocurrencias de [a] con b, obtenemos estos tipos:

f :: a -> b -> b 
z :: b 

Y ahora, por supuesto, del tipo de foldr se basa en este principio :

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

Por lo tanto, dada la construcción/semántica de observación de las listas, foldr es el de que los MOS t natural. Puede leer el tipo como "dígame qué hacer con un (:) y qué hacer con un [], y me desharé de una lista para usted".

Array no tiene esta propiedad; construye una matriz a partir de una lista de asociaciones (Ix i => [(i,a)]), y el tipo realmente no expone ninguna estructura recursiva: una matriz no se construye a partir de otras matrices mediante un constructor recursivo como lo haría una lista o un árbol.

+0

+1 para "dime qué hacer con un' (:) 'y qué hacer con un' [] ', y me desharé de una lista para ti". - ¡Me gusta mucho! – epsilonhalbe

Cuestiones relacionadas