2011-09-10 13 views
5

¿Alguien puede dar un ejemplo que muestra la adición de dos matrices en Haskell, por favor?Agregar dos matrices de valores float en Haskell

Soy bastante nuevo en Haskell, y generalmente me parece que puedo aprender más rápido al tomar algo simple que entiendo en un idioma y ver cómo otro programador podría hacerlo en su idioma.

Sería genial ver un código que crea dos conjuntos de flotantes y llama a una función que da como resultado una matriz con los valores sumados. Algo equivalente al siguiente código de C.

void addTwoArrays(float *a, float *b, float *c, int len) { 
    int idx=0; 
    while (idx < len) { 
     c[idx] = a[idx] + b[idx]; 
    } 
} 

int N = 4; 
float *a = (float*)malloc(N * sizeof(float)); 
float *b = (float*)malloc(N * sizeof(float)); 
float *c = (float*)malloc(N * sizeof(float)); 

a[0]=0.0; a[1]=0.1; a[2]=0.2; a[3]=0.4; 
b[0]=0.0; b[1]=0.1; b[2]=0.2; b[3]=0.4; 
addTwoArrays(a,b,c,N); 

Ver el código de Haskell que logró el mismo resultado me ayudaría a comprender mucho. Supongo que la versión de Haskell crearía la matriz de resultados y la devolvería, como c = addTwoArrays (a, b, N)?

Gracias.

Respuesta

5

en Haskell, para esta pregunta, que va a utilizar listas en lugar de matrices (matriz sin embargo, vector existir en Haskell, gracias Thomas M. Dubuisson por su comentario) y el código serán así

addTwoArrays :: (Num a) => [a]->[a]->[a] 
addTwoArrays _ [] = [] 
addTwoArrays [] _ = [] 
addTwoArrays (x:xs) (y:ys) = (x+y) : (addTwoArrays xs ys) 

Este función tomará dos matrices que tienen valores numéricos (entradas, flotantes, etc.) y los suma hasta la longitud más corta.

Sin embargo podemos escribir misma función con el uso de las características del lenguaje funcionales:

addTwoArrays :: (Num a) => [a]->[a]->[a] 
addTwoArrays xs ys :: zipWith (+) xs ys 

Ambas funciones se llevarán dos listas y devuelve la suma, basado en el más corto.

addTwoArrays [1.0, 2.0, 3.0] [2.0, 3.0, 4.0] --returns [3.0, 5.0, 7.0] and 

addTwoArrays [1.0, 2.0, 3.0] [2.0, 3.0] --returns [3.0, 5.0] 
+4

O simplemente simplemente 'addTwoArrays = zipWith (+)'. – hammar

+0

Tienes razón, sin embargo, pensé que para un nuevo alumno, sería mejor mostrar una definición de función normal que una curry. Dado que estos son los temas en los capítulos posteriores :) –

+0

ver http://www.willamette.edu/~fruehr/haskell/evolution.html –

10

Por simplicidad, voy a utilizar listas (vinculadas) en lugar de matrices, ya que se pueden crear más fácilmente usando listas literales.

a = [0, 0.1, 0.2, 0.4] 
b = [0, 0.1, 0.2, 0.4] 
c = zipWith (+) a b 

zipWith es una función que toma otra función y dos listas y luego crea una nueva lista mediante la aplicación de la función dada a cada par de elementos de las listas al mismo índice. Así que aquí la función que damos a zipWith es + y, por lo tanto, agrega los elementos de las dos listas.

Si quisiéramos hacer esto sin usar zipWith podríamos definir addTwoLists así:

addTwoLists [] _ = [] 
addTwoLists _ [] = [] 
addTwoLists (x:xs) (y:ys) = (x+y) : (addTwoLists xs ys) 

La lógica aquí es que cuando una de las listas está vacía, addTwoLists devolverá una lista vacía. De lo contrario, devolverá la suma de las cabeceras de las dos listas (es decir, a+b) antes del resultado de agregar juntas sus colas.

4

Además de las otras respuestas: Las funciones de compresión también existen para Vector s. Los vectores son matrices reales y listas no vinculadas, aunque la computadora puede optimizar los vectores si es posible. Mira el enlace de arriba para obtener más información.

+0

+1 solo por mencionar Vector. –