2010-11-18 17 views
1

我被要求做一個計算像添加號碼的權力,在Haskell與與foldl

1^2 + 2^2 + 3^2 ... 

雖然我覺得它很容易與列表理解實施哈斯克爾功能

sum [ k^2 | k <- [1..100]] 

或地圖

sum (map (\x -> x*x) [1..100]) 

我有一些困難得到如何實現它foldls。

如果我沒看錯的,需要不超過在遞歸函數3個參數少,實現與這樣的結果:

  1. 當前位置(1 ...直到n)
  2. 的電流和
  3. 在哪裏停止

即使我定義這個功能,它仍然會返回一個元組,而不是數字(如我需要它!)。

任何人都可以提供一些線索,我可能會錯過什麼嗎?

感謝

回答

5

「當前位置」(實際上是列表中的下一項,就像在地圖和列表理解版本中一樣)以及停止位置隱含在正在摺疊的列表中。當前總和是摺疊的「累加器」參數。所以,填空:

foldl (\runningSum nextNumber -> ____) 0 [1..100] 
+1

順便提一句,我通常也會推薦'foldl'(在Data中定義)。列表),這迫使累加器在每一步都被評估。使用GHC進行編譯時,無論如何都會得出結論,但在GHCi或Hugs中,它可以在恆定空間運行或內存耗盡之間進行區分。 – mokus 2010-11-18 13:46:15

6

如果你看看sum的定義,它只是sum = foldl (+) 0。因此,如果在任一解決方案中將sum替換爲foldl (+) 0,則可以使用foldl解決方案。

您還可以通過使用foldl來刪除列表解析或map的需求,該函數使用將第二個參數的平方加上其第一個參數的函數。

我不確定你對遞歸函數的考慮在哪裏。如果您使用的是foldl,則不需要使用遞歸(除非目前使用遞歸實現foldl)。

然而,你錯了一個遞歸函數需要三個參數:一個遞歸函數將列表中每個元素的平方相加,最直接的方式是通過獲取一個列表並將該列表的頭部添加到調用列表尾部的函數的結果。基本情況是squareSum [] = 0。雖然這與foldl沒有任何關係。

+0

雖然這個想法很好,這聽起來有點像作弊。我不相信這就是老師所要求的:( – 2010-11-18 13:39:22

+0

@devoured:我不知道他可能會問什麼(你可能應該擺脫'map'和列表解析在我的解釋第二段)如果賦值語句使用'foldl',則肯定不應該使用顯式遞歸。 – sepp2k 2010-11-18 13:43:34