Haskell使用mapReduce定义Merge

时间:2010-11-04 17:52:57

标签: haskell

我正在尝试使用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函数接受输入并将其转换为稍后由reduce函数使用的内容。

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)

有人可以帮帮我吗? 提前谢谢。

1 个答案:

答案 0 :(得分:2)

假设传入的列表已排序,则以下函数与您的vanilla 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:这应该返回剩下的列表,而不是空列表(为了简洁,这是用(++)完成的。)