2011-09-10 40 views
5

任何人都可以提供一個示例來顯示在Haskell中添加兩個數組嗎?在Haskell中添加兩個浮點值數組

我對Haskell相當陌生,我通常會發現,通過簡單地理解一種語言並瞭解其他程序員如何使用他們的語言來學習,我可以更快地學習。

很高興看到一些代碼創建兩個浮點數組並調用一個產生具有總和值的數組的函數。相當於以下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); 

看到Haskell代碼,取得了相同的結果將有助於我的理解了很多。我猜Haskell版本會創建結果數組並返回它,就像c = addTwoArrays(a,b,N)一樣?

謝謝。

回答

5

在Haskell,對於這個問題,你會用列表,而不是陣列(但是數組,向量存在在Haskell,感謝托馬斯M DuBuisson他評論)和代碼會是這樣

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

這函數將採用兩個數組的數值(整數,浮點數等)並將它們相加,直到較短的長度。

但是我們可以把同樣的功能與使用功能性語言功能:

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

這兩個函數將兩個列表,並返回總和的基礎上,更短的一個。

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

或者只是簡單的'addTwoArrays = zipWith(+)'。 – hammar

+0

你是對的,但是我認爲對於一個新的學習者來說,最好是展示一個正常的函數定義而不是咖喱飯。由於這些是後面章節中的主題:) –

+0

請參閱http://www.willamette.edu/~fruehr/haskell/evolution。html –

10

爲了簡單起見,我將使用(鏈接)列表而不是數組,因爲它們可以更容易地使用列表文字創建。

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

zipWith是一個函數,它接受另一個函數和兩個列表,然後通過相同的索引在施加給定的功能到每對列表的元素創建一個新的列表。所以在這裏我們給zipWith的函數是+,因此它添加了兩個列表的元素。

如果我們想要做到這一點,而無需使用zipWith我們可以定義addTwoLists這樣的:

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

的邏輯在這裏是當其中一個列表是空的,addTwoLists會返回一個空列表。否則它將返回兩個列表的頭部總和(即a+b),並將它們的尾部加在一起。

4

除了其他答案:茲拉功能也存在Vector s。矢量是真正的數組而不是鏈接列表,儘管計算機可能會優化矢量。查看上面的鏈接以獲取更多信息。

+0

+1僅僅用於提及Vector。 –