Мне дали BST в haskell, который может добавлять, удалять, искать, находить Макс и удалять Макс. Мне нужно создать функцию, которая преобразует данные в структуру списка.

bstToList:: (BST k v) -> [String]
bstToList EmptyBST = ["hi"]
bstToList (BSTNode k v nl nr) = bstToList nl ++ bstToList nr

Причина, по которой у меня есть EmptyBST = ["привет"], заключалась в том, чтобы проверить, что он возвращал. При вводе

bstToList (bstAdd 1 "Phil" (bstAdd 2 "Ip" EmptyBST))

Возвращает список ["привет", "привет", "привет"]. И мне неясно, почему все возвращает пустой список. Предположим, что все функции, кроме bstToList, верны и работают правильно. Любая помощь приветствуется!

0
Phirip 14 Май 2013 в 10:21

1 ответ

Лучший ответ

Линия

bstToList (BSTNode k v nl nr) = bstToList nl ++ bstToList nr

Не использует значение в узле, поэтому вы всегда получаете данные только из битов EmptyBST.

Тебе нужно

BstToList :: BST k v -> [v] 
bstToList EmptyBST = []
bstToList (BSTNode k v nl nr) = bstToList nl ++ [v] ++ bstToList nr

Чтобы значение в этом узле было вставлено между значениями слева и справа от него. (Это называется обходом по порядку.)

Если вы хотите перечислить и ключи, и значения, которые вам нужны

BstToList :: BST k v -> [(k,v)] 
bstToList EmptyBST = []
bstToList (BSTNode k v nl nr) = bstToList nl ++ [(k,v)] ++ bstToList nr

Обратите внимание на скобки вокруг (k, v) - они превращают два предмета в пару. То же самое и с подписью типа. (Синтаксис отсутствующей пары является причиной ошибки.)

[k, v] может работать как данные, только если k и v одного типа, а [k, v] не может работать как тип.

3
AndrewC 14 Май 2013 в 10:55
Отлично, спасибо! Я никогда не понимал, что не показываю никаких значений для результатов. Я попытался указать оба типа [k, v] в качестве возвращаемого типа, и теперь это дает мне ошибку: Kind mis-match Expected kind 'OpenKind', but '[k, v]' has kind '[*]' In the type signature for 'bstToList': bstToList :: (BST k v) -> '[k, v]
 – 
Phirip
14 Май 2013 в 10:42
Большое спасибо, вы очень помогли мне понять! : D
 – 
Phirip
14 Май 2013 в 10:52
Вы можете вдвое уменьшить свой постоянный коэффициент, избегая использования ++.
 – 
jub0bs
22 Фев 2015 в 17:07
Вы имеете в виду переход через ([v] -> [v]) и использование leftBit . (v:) . rightBit? Я не уверен, что у ОП была подходящая зона ближайшего развития для оптимизации.
 – 
AndrewC
23 Фев 2015 в 02:32
Да, я это имел в виду. Я просто подумал, что упомяну об этом, но вы правы: OP, вероятно, еще не было, по крайней мере, на момент запроса.
 – 
jub0bs
23 Фев 2015 в 07:55