Не исчерпывающая ошибка шаблона при декодировании дерева Хаффмана? - PullRequest
1 голос
/ 26 октября 2019

Я пытаюсь превратить дерево Хаффмана и поток битов в список символов плюс логическое значение, указывающее, использовали ли выходные данные все входные биты. Вот пример:

decode xyz_code [True,False,True,True,True,False,False,True] = 
("yzyx",False)

Вот что у меня есть, но это не работает. Что не так? Помогите!

data BTree a = Leaf a | Fork (BTree a) (BTree a) deriving (Show, Eq)

decode :: BTree a -> [Bool] -> ([a], Bool)
decode _ [] = ([],True)
decode (Leaf v) [bs] = ([v], bs)
decode (Fork left right) (b:bs)
   | b         = decode right bs
   | otherwise = decode left bs

Ответы [ 2 ]

1 голос
/ 26 октября 2019
  • _ [] охватывает пустые списки
  • (Fork left right) (b:bs) охватывает непустые списки для Fork с
  • (Leaf v) [bs] охватывает списки длиной 1 для Leaf с

Так чего же не хватает, о чем вас предупреждает компилятор? Списки длиной> 1 для Leaf с. Вы должны определить этот случай как нечто. Если достижение этого состояния не является логически допустимым, допустима ошибка:

data BTree a = Leaf a | Fork (BTree a) (BTree a) deriving (Show, Eq)

decode :: BTree a -> [Bool] -> ([a], Bool)
decode _ [] = ([], True)
decode (Leaf v) [bs] = ([v], bs)
<b>decode (Leaf v) _ = error "Too much code left at leaf"</b>
decode (Fork left right) (b:bs)
   | b         = decode right bs
   | otherwise = decode left bs
1 голос
/ 26 октября 2019

Заголовок указывает на то, что вы получили предупреждение о неполном совпадении с шаблоном. Рассмотрим это:

58567334.hs:6:1: warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for `decode': Patterns not matched: (Leaf _) (_:_:_)
  |
6 | decode _ [] = ([],True)
  | ^^^^^^^^^^^^^^^^^^^^^^^^...

Это говорит о том, что шаблон, включающий любой Leaf со списком логических значений длиннее двух, не охватывается.

Первый шаблон, который соответствует [] соответствует пустому списку.

Следующий шаблон, соответствующий [bs], соответствует списку с единственным элементом с именем bs. Это распространенная ошибка.

Возможно, вам вместо этого нужен этот шаблон:

decode (Leaf v) bs = -- ...

, где bs - это значение [Bool] (т. Е. Список логических значений).

Теперь вам нужно выяснить, как объединить этот список логических значений в один Bool.

...