2015-11-19 3 views
2

Я пытаюсь уменьшить дерево в список, но я застрял здесь .. любые предложения приветствуются ..Сокращение дерева в список в Haskell

data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving (Eq, Show) 
treeToList :: (Ord a) => Tree a -> [a] 
treeToList (Node root left right) = treeToList left ++ [root] ++ treeToList right 

Ожидая Результат:

ghci> treeToList (Node (Leaf 1) 2 (Node (Leaf 3) 4 (Leaf 5))) 

[1,2,3,4,5] 
+0

В будущем сообщение об ошибке или неверный вывод, который вы получите, полезны тем, кто отвечает на ваши вопросы. – luqui

+0

Какова цель ограничения Ord? Это необязательно, это часть вашего решения или часть вашего задания? 'treeToList :: Tree a -> [a]' достаточно. – Franky

ответ

6

у вас есть две ошибки:

  1. Non-exhaustiv e pattern (для конструктора Leaf).
  2. И в шаблоне для Node вы соответствуете root как значение левого дерева (Tree a), а не a.

Таким образом, результат должен выглядеть следующим образом:

data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving (Eq, Show) 

treeToList :: (Ord a) => Tree a -> [a] 
treeToList (Leaf v) = [v] 
treeToList (Node left root right) = treeToList left ++ [root] ++ treeToList right 
*Main> treeToList (Node (Leaf 1) 2 (Node (Leaf 3) 4 (Leaf 5))) 
[1,2,3,4,5] 
+0

Спасибо за исправление :) – John

+0

Как я могу добавить функцию идентификации для выполнения sum say, ниже моя функция с типом: treeToList :: Tree a -> (a -> b) -> (b -> a -> b - > b) -> b * Main> treeToList (Узел (лист 1) 2 (Узел (лист 3) 4 (лист 5))) сумма id, где сумма t1 v t2 = t1 + v + t2, тогда выход равен 15 – John

+0

@ Джон, я понятия не имею, почему тип функции настолько сложный. Функция с аргументом функции должна выглядеть так: 'treeToFunElem :: Tree a -> (a -> a -> b) -> b', поэтому результат будет иметь тип' b', который может быть или не быть тот же тип, что и 'a' (например, дерево целых чисел и принимает квадратные корни из них с преобразованием в double). – m0nhawk

3

риффов на абсолютно правильный ответ m0nhawk, я бы предложил следующий совет. Когда вы пишете функцию, которая соответствует шаблону по типу алгебраических данных, например Tree, начните с написания шаблона о том, как будет структурирована функция. В этом случае, учитывая определение типа:

data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving (Eq, Show) 

... и эта подпись функции:

treeToList :: (Ord a) => Tree a -> [a] 

... вы можете начать с написания шаблона, как этот, который только расширяется из две альтернативы в Tree типа и их компоненты:

treeToList (Leaf value) = _ 
treeToList (Node left value right) = _ 

Прочитайте _ (подчеркивание), как «пробелы», чтобы заполнить позже. Это действительно правильный синтаксис в последних версиях GHC, называемый «дырой», поэтому компилятор вам напомнит, что вам нужно его заполнить.

Выписывая шаблон, подобный этому, и убедитесь, что вы покрываете все альтернативы типа, с которым вы работаете, значительно уменьшают риск столкновения с проблемой № 1, о которой указал m0nhawk.

Смежные вопросы