归并排序的haskell实现 (参考 haskell函数式编程入门)

源码及工程:https://github.com/bzhkl/haskellStudy/

module Main where
import Control.Monad.Writer


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


indent n = showString (take (4*n) (repeat ' '))


nl = showChar '\n'


mergesort :: Int -> [Int] -> Writer String [Int]
mergesort l [] = do
  return []


mergesort l s@[x] = do
  return [x]


mergesort l s@xs = do
  tell $ (indent l.showString "mergesort:   ".shows s.showString "\n") ""
  let (a1,a2) = splitAt (length s `div` 2) xs
  curMergeResult <- liftM2 merge (mergesort (l+2) a1) (mergesort (l+2) a2)
  tell $ (indent l.showString "after merge: " .shows curMergeResult) "\n"
  return curMergeResult
  


main :: IO ()
main = do
  let res = runWriter $ mergesort 0 [5,4,3,10,9,101,2,1]
  putStrLn $show $ fst $res
  putStrLn $ snd $ res

运行输出: 

[1,2,3,4,5,9,10,101]
mergesort:   [5,4,3,10,9,101,2,1]
        mergesort:   [5,4,3,10]
                mergesort:   [5,4]
                after merge: [4,5]
                mergesort:   [3,10]
                after merge: [3,10]
        after merge: [3,4,5,10]
        mergesort:   [9,101,2,1]
                mergesort:   [9,101]
                after merge: [9,101]
                mergesort:   [2,1]
                after merge: [1,2]
        after merge: [1,2,9,101]
after merge: [1,2,3,4,5,9,10,101]

编译依赖的库:

build-depends:   base >= 4.7 && < 5
          , mtl

 

posted @ 2016-12-21 16:24  hambda  阅读(798)  评论(0编辑  收藏  举报