1
1
import qualified Data.Map as M
2
2
import Data.List (insert , sort )
3
3
4
- data Tree a = Nil
5
- | Leaf Int a
4
+ data Tree a = Leaf Int a
6
5
| Node Int (Tree a ) (Tree a )
7
6
deriving (Show , Eq )
8
7
9
8
freq :: Tree a -> Int
10
- freq Nil = 0
11
9
freq (Leaf i _) = i
12
10
freq (Node i _ _) = i
13
11
@@ -19,10 +17,10 @@ getFrequencies = toSortedList . M.fromListWith (+) . flip zip (repeat 1)
19
17
where toSortedList = sort . map swap . M. toList
20
18
swap (a, i) = (i, a)
21
19
22
- buildTree :: (Ord a ) => [a ] -> Tree a
20
+ buildTree :: (Ord a ) => [a ] -> Maybe ( Tree a )
23
21
buildTree = build . map (uncurry Leaf ) . getFrequencies
24
- where build [] = Nil
25
- build [t] = t
22
+ where build [] = Nothing
23
+ build [t] = Just t
26
24
build (t1: t2: ts) = build $ insert (Node (freq t1 + freq t2) t1 t2) ts
27
25
28
26
data Bit = Zero | One
@@ -31,18 +29,20 @@ instance Show Bit where
31
29
show Zero = " 0"
32
30
show One = " 1"
33
31
34
- encode :: (Ord a ) => [a ] -> (Tree a , [Bit ])
32
+ encode :: (Ord a ) => [a ] -> (Maybe ( Tree a ) , [Bit ])
35
33
encode s = (tree, msg)
36
34
where
37
35
tree = buildTree s
38
36
msg = concatMap (table M. ! ) s
39
- table = M. fromList $ mkTable (tree, [] )
40
- mkTable (Nil , _) = []
37
+ table = case tree of
38
+ Nothing -> M. empty
39
+ Just t -> M. fromList $ mkTable (t, [] )
41
40
mkTable (Leaf _ a, p) = [(a, reverse p)]
42
41
mkTable (Node _ t1 t2, p) = concatMap mkTable [(t1, Zero : p), (t2, One : p)]
43
42
44
- decode :: (Ord a ) => Tree a -> [Bit ] -> [a ]
45
- decode t = path t
43
+ decode :: (Ord a ) => Maybe (Tree a ) -> [Bit ] -> [a ]
44
+ decode Nothing _ = []
45
+ decode (Just t) m = path t m
46
46
where path (Leaf _ a) m = a : path t m
47
47
path (Node _ t1 _) (Zero : m) = path t1 m
48
48
path (Node _ _ t2) (One : m) = path t2 m
0 commit comments