2011-09-10 15 views
5

Czy ktoś może podać przykład pokazujący dodanie dwóch tablic w Haskell?Dodawanie dwóch tablic wartości zmiennoprzecinkowych w Haskell

Jestem całkiem nowy dla Haskella i generalnie uważam, że mogę się szybciej uczyć, biorąc coś prostego, co rozumiem w jednym języku i widząc, jak inny programista może to zrobić w ich języku.

Byłoby wspaniale widzieć kod, który tworzy dwie tablice zmiennych i wywołuje funkcję, która skutkuje tablicą z sumowanymi wartościami. Coś równoznacznego z następującym kodem 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); 

Zobaczenie kodu Haskella, który osiągnął ten sam rezultat, bardzo pomogłoby mi w zrozumieniu. Domyślam się, że wersja haskell utworzyłaby tablicę wyników i zwróciła ją, jak c = addTwoArrays (a, b, N)?

Dzięki.

Odpowiedz

5

w Haskell, na to pytanie, będzie korzystać z list zamiast tablic (jednak tablicę, wektor istnieć w Haskell, dzięki Thomas M. Dubuisson jego komentarzu) i kod będzie tak

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

ten funkcja pobiera dwie tablice, które mają wartości numeryczne (int, float, itp.) i sumuje je do krótszych długości.

Jednak możemy napisać tę samą funkcję przy użyciu funkcjonalnych cech językowych:

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

Obie funkcje weźmie dwie listy i zwraca sumę, w przeliczeniu na jeden krótszy.

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

Lub po prostu 'addTwoArrays = zipWith (+)'. – hammar

+0

Masz rację, jednak myślałem, że dla nowego ucznia, lepiej byłoby pokazać normalną definicję funkcji niż curry. Ponieważ są to tematy w późniejszych rozdziałach :) –

+0

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

10

Dla uproszczenia zamierzam użyć (połączonych) list zamiast tablic, ponieważ można je łatwiej tworzyć za pomocą literałów listy.

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

zipWith jest funkcją, która wykonuje inną funkcję i dwie listy, a następnie tworzy nową listę poprzez zastosowanie danej funkcji do każdej pary elementów list w tym samym indeksie. Tak więc funkcja, którą dajemy zipWith, to + i tym samym dodaje elementy z dwóch list.

Gdybyśmy chcieli to zrobić bez użycia zipWith moglibyśmy określić addTwoLists takiego:

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

Logika jest to, że gdy jeden z list jest pusta, addTwoLists zwróci pustą listę. W przeciwnym razie zwróci sumę głów z dwóch list (tj. a+b) dodanych do wyniku dodania ich ogonów.

4

Oprócz innych odpowiedzi: funkcje zrzutu istnieją również dla Vector s. Wektory to prawdziwe tablice i niepołączone listy, chociaż komputer może optymalizować wektory, jeśli to możliwe. Spójrz na powyższy link, aby uzyskać dalsze informacje.

+0

+1 tylko po to, aby wspomnieć o Vector. –

Powiązane problemy