2010-11-04 60 views
0

我試圖用mapReduce遞歸的方式來定義merge定義合併。哈斯克爾使用MapReduce的

mapReduce被定義爲

mapReduce mapFn wayAheadFn turnAroundCond turnAroundFn reduceFn xin 
    | (turnAroundCond xin) = turnAroundFn xin 
    | otherwise = 
     reduceFn 
     (mapFn xin) 
     (mapReduce mapFn wayAheadFn turnAroundCond turnAroundFn reduceFn (wayAheadFn xin)) 

這些是對應關係。

turnAroundCond:終止條件是停止。

mapFn:map函數獲取輸入,並將其轉換爲東西被精簡函數以後使用。

wayAheadFn:一路預讀功能轉換輸入的形式傳遞給遞歸調用。

reduceFn:reduce函數將函數應用於(a)mapFn留下的內容和(a)遞歸調用返回的內容。

我做了什麼至今:

merge' xs ys = 
    mapReduce 
     (\(x:_, y:_) -> if x <= y then x else y)  -- mapFn. 
     (\(x:xs, y:ys) -> (xs, y:ys)) -- wayAheadFn. 
     (\(x, y) -> null x || null y) -- turnAroundCond. 
     (\_ -> [])      -- turnAroundFn. 
     (:)       -- reduceFn. 
     (xs, ys)      --input 

但是當我運行merge',它給了我這樣的:

merge' [1,2] [3,4] 
[1,2] 

合併應給予[1,2,3,4]。其分類和合並兩個列表

正常語法將

merge [] ys = ys 
merge xs [] = xs 
merge (x:xs) (y:ys) 
    | x <= y = x : (merge xs (y:ys)) 
    | otherwise = y : (merge (x:xs) ys) 

誰能幫助我,好嗎? 在此先感謝。

+3

嗨,我編輯了你的帖子,把你的代碼放在代碼塊中。要在將來自己做,可以在每行代碼前放4個空格,或者突出顯示代碼塊中的文本,然後單擊編輯區域頂部的「010101」按鈕。 :-) – 2010-11-04 18:00:26

+2

你還沒有告訴我們'合併'應該給出什麼輸出,或者爲什麼。 – dave4420 2010-11-04 18:38:32

+0

'merge'是否有兩個排序列表?這似乎是'合併'會產生所需輸出的唯一方式。 – Paul 2010-11-04 19:26:40

回答

2

假設所傳遞的列表進行排序,下面的功能是一樣的香草merge

merge' xs ys = 
    mapReduce 
     (\(x:_, y:_) -> if x <= y then x else y)      -- mapFn. 
     (\(x:xs, y:ys) -> if x <= y then (xs, y:ys) else (x:xs, ys)) -- wayAheadFn. 
     (\(x, y) -> null x || null y)         -- turnAroundCond. 
     (\(x, y) -> x ++ y)            -- turnAroundFn. 
     (:)                -- reduceFn. 
     (xs, ys)              -- input 

你的merge'版本有兩件事情不對的地方,即:

  • wayAheadFn:你只有剝去第一列表的前面,而不是剝離,是由所選取的一個地圖步驟。
  • turnAroundFn:這應該返回剩下的列表,而不是空列表(爲了簡潔,這是用(++)完成的)。
+0

感謝您的回覆。你的評論讓我明白我出錯的地方。 – user497512 2010-11-09 20:35:19