[haskell]写了一个哈夫曼编解码的程序

初学者,纯练手。haskell的类型系统过于强大,以致写程序时大量时间是跟类型不匹配打交道,不过带来的好处就是一旦编译通过,多半就能work了

 1 data Tree a = Empty | Branch a (Tree a) (Tree a)
 2     deriving (Show, Eq)
 3 isLeaf (Branch a Empty Empty) = True
 4 isLeaf _ = False
 5 value::(Num t, Ord t, Show t) => Tree t -> t
 6 value Empty = 0
 7 value (Branch a _ _ ) = a
 8 getMinOne::(Num a, Ord a) => [Tree a] -> (Tree a, [Tree a])
 9 getMinOne [] = (Empty, [])
10 getMinOne (x:[]) = (x, [])
11 getMinOne (x:xs) = let (m, xxs) = (getMinOne xs) in
12     if (value x) < (value m) then ( x, [m]++xxs ) else
13         (m, [x]++xxs)
14 getMinTwo [] = (Empty, Empty, [])
15 getMinTwo xs = let (one, last) = (getMinOne xs) in
16                     let (two, llast ) = (getMinOne last) in
17                         (one, two, llast)
18 haff :: (Ord a, Num a) => [a] -> [Tree a]
19 haff [] = []
20 haff xs = haffs ( map (\x -> Branch x Empty Empty) xs ) where
21     haffs xxs = if ((length xxs) == 1then xxs else
22         let ( one, two, last ) = (getMinTwo xxs) in
23             haffs ([(Branch ( (value one) + (value two) ) one two )] ++ last )
24 
25 encodOne ch (Branch v l f) result = if ( v == ch && (isLeaf (Branch v l f)) ) then result else
26     if ( v /= ch && (isLeaf (Branch v l f))) then "" else
27         if( lv == "" && rv /= "" ) then rv else lv where
28             lv = (encodOne ch l ("0"++result))
29             rv = (encodOne ch f ("1"++result))
30 haffEncod [] = []
31 haffEncod xs = let [t] = (haff xs) in
32     map ( \x -> encodOne x t "" ) xs
33 
34 decodOne:: (Ord a, Num a) => [Char] -> (Tree a) -> a
35 decodOne (x:[]) (Branch v l r) = if [x] == "0" then (value l) else (value r)
36 decodOne (x:xs) (Branch v l r)  = if [x] == "0" then decodOne xs l else decodOne xs r
37 
38 haffDecod :: (Ord a, Num a) => [[Char]] -> [a] -> [a]
39 haffDecod [] _ = []
40 haffDecod xs [] = []
41 haffDecod xs dic = let [t] = (haff dic) in
42     map ( \x -> decodOne x t ) xs

 

 

 

 最近在做Ninety-Nine Haskell Problems已经做到第80题了

 

 

posted @ 2010-08-23 18:48  gussing  阅读(811)  评论(0编辑  收藏  举报