2012-02-02 49 views
3

目前我哈斯克爾瞎搞。我對Haskell的知識(以及一般的函數式語言)仍然很低,但我正在努力。 真正困擾我的是一個(我認爲)簡單的任務:摺疊嵌套列表,每一個深度倍。哈斯克爾摺疊嵌套列表

fcalc = foldr (\x y -> (foldr (**) 1 x) * (foldr (**) 1 y)) [1.0, 1.0] [[2.0, 3.0], [4.0, 5.0]] 

它應該做什麼:2^3 * 4^5其中^由lambda'd內摺疊完成。可悲的是它不起作用。

Occurs check: cannot construct the infinite type: t0 = [t0] 
In the third argument of `foldr', namely `y' 

我讀了一些關於給定的「無限類型」的錯誤,主要表明一個變量被用作例如「元素,而它是一個列表。這讓我想到了外部問題的第二個參數是問題,但沒有成功。 我只是不明白。 :/

+1

好吧,我不知道你是否AREN對此不會採取錯誤的方式。首先,你打破了我的一個經驗法則:你不使用摺疊來直接解決問題,而是使用它們來實現一些中間抽象來解決你的問題。其次,我想知道列表和嵌套列表是否真的是您嘗試執行的正確數據結構;我感覺你正在處理某種抽象語法樹更好地服務的問題區域。 – 2012-02-02 20:57:06

回答

4

您的問題是你試圖做你的蓄電池的褶皺內a^b計算,同時還做每一個元素。你真正想要的是像

fcalc = foldr (\x y -> (foldr (**) 1 x) * y) 1 [[1.0, 1.0], [2.0, 3.0], [4.0, 5.0]] 

記住的foldr每一步的輸出是否插好爲接下來的步驟(例如,在這種情況下,y變量)的第二個參數。由於您的foldr一步返回一個數字,y變量已經是一個數字,所以你不能在它摺疊。

+0

哦,親愛的,我怎麼會想到以這樣一種錯誤的方式...非常感謝糾正我的褶皺的理解。 – Julian 2012-02-02 20:42:46

1

不回答你的問題,但解決你的問題的另一種方式:

haskell> sum $ map ((**) <$> (!! 0) <*> (!! 1)) xs 
1032.0 

或者,如果你不舒服的pointfree:

haskell> sum $ map (\x -> let (a:b:_) = x in a ** b) xs 
1032.0 
+2

如果你想編碼的事實,你只看到前兩個元素,你可以切換到使用元組來代替。 – 2012-02-02 20:46:47

+0

當然,但只有在編譯時知道它將成爲一個元組。 – missingfaktor 2012-02-03 04:25:05