Доброго времени суток.
Почитав статьи на RSDN решил изучить декларативную парадигму, в частности функциональный подход.
В качестве упражнений пишу расчеты лабораторных работ по Теории Информации на Haskell. И вот загвоздка, не могу сгенерировать бинарное дерево:
module Main where
-- бинарное дерево
data BinTree a = Leaf a | Branch (BinTree a) (BinTree a)
-- обходим дерево, генерируем для каждого символа его код
calcRule :: BinTree (Char,Integer) -> [(Char,String)]
calcRule (Branch lhs rhs) =
let
calc' :: String -> BinTree (Char,Integer) -> [(Char,String)]
calc' code (Leaf x) = [(fst x, code)]
calc' code (Branch lhs rhs) = (calc' (code ++ "0") lhs) ++ (calc' (code ++ "1") rhs)
in
(calc' "0" lhs) ++ (calc' "1" rhs)
-- генерируем дерево
genTree :: [(Char,Integer)] -> BinTree (Char,Integer)
{-
-- вот такое дерево должно получиться
genTree _ = Branch (Branch (Leaf ('A',15))
(Leaf ('B',7)))
(Branch (Leaf ('C',6))
(Branch (Leaf ('D',6))
(Leaf ('E',5))))
-}
genTree sepp = undefined
-- получаем список пар (символ, код) из списка (символ, кол-во)
getRule :: [(Char,Integer)] -> [(Char,String)]
getRule sorted_ch_count_pairs =
let
tree = genTree sorted_ch_count_pairs
in
calcRule tree
--------
main =
let
-- список (символ, кол-во)
char_count_pairs = [('A',15), ('B',7), ('C',6), ('D',6), ('E',5)]
in
print $ getRule char_count_pairs
Визуально дерево должно выглядеть вот так:
http://en.wikipedia.org/wiki/Shannon-Fano_coding
Группы символов делятся по алгоритму:
1. сумма первой группы (p1) и второй (p2) равна нулю;
2. p1 <= p2 ?
* да: добавить в первую группу символ с начала таблицы;
* нет: добавить во вторую группу символ с конца таблицы;
3. если все символы разделены на группы, то завершить алгоритм, иначе перейти к шагу 2.
Т.е. надо как-то рекурсивно поделить список [('A',15), ('B',7), ('C',6), ('D',6), ('E',5)] на группы и натянуть результат на дерево. Уже 3-ий день не могу это сделать

Помогите кодом или советом. Спасибо.