#haskell #preorder
#haskell #предварительный заказ
Вопрос:
Я пытаюсь создать функцию предварительного заказа для обхода IntTree.
Класс дерева выглядит следующим образом
data IntTree = Empty | Branch IntTree Int IntTree deriving (Show, Eq)
У меня есть два вопроса
1. Я получаю ошибки, как показано ниже.
E:HaskellUebungsblatt_2_Aufgabe_2_a.hs:7:14: error:
* Expected kind `* -> Constraint', but `IntTree' has kind `*'
* In the type signature: preorder :: (IntTree c) => c -> [a]
|
7 | preorder :: (IntTree c) => c->[a]
| ^^^^^^^^^
[Finished in 0.5s]
Я не понимаю, почему. Они произошли в этой следующей строке
preorder :: (IntTree c) => c->[a]
-
Я думаю, что следующая строка неверна. Я думаю, мне нужно написать другие выражения вместо » l: предварительный заказ a: предварительный заказ r: [] «
preorder Branch a l r = l : preorder a : preorder r:[]
Заранее благодарю вас за помощь!!
main :: IO () -- This says that main is an IO action.
main = return () -- This tells main to do nothing
data IntTree = Empty | Branch IntTree Int IntTree deriving (Show, Eq)
preorder :: (IntTree c) => c->[a]
preorder Empty = []
preorder Branch Empty x Empty = [x]
preorder Branch a l r = l : preorder a : preorder r:[]
Ответ №1:
Для вопроса 1:
preorder :: (IntTree c) => c->[a]
Вы путаете классы и типы данных. IntTree
был объявлен с помощью data
, поэтому это не класс типов, а обычный тип данных, такой как Bool
или Int
. Он используется таким же образом:
preorder :: IntTree -> [a]
Во-вторых, вы не возвращаете список какого-либо типа a
(строчные буквы — это переменные типа), вы возвращаете конкретно список Int
s, потому что это то, что содержит дерево. Итак, вы должны так сказать:
preorder :: IntTree -> [Int]
Ответ №2:
Для вопроса 1: подпись
preorder :: (IntTree c) => c->[a]
неверно: IntTree
это не класс типов, это обычный тип, поэтому мы можем использовать его как есть.
preorder :: IntTree -> [Int]
Конечный тип должен быть Int
, поскольку мы создаем список целых чисел, а не список [a]
для любого a
.
Для вопроса 2: :
добавляет элемент к списку, он имеет тип
(:) :: a -> [a] -> [a]
Следовательно, он не объединяет два списка. Для этого используйте вместо
( ) :: [a] -> [a] -> [a]
как в
preorder (Branch a l r) = l : preorder a preorder r
(Нет необходимости использовать []
в конце)
Комментарии:
1. Черт возьми, вы добавили раздел с вопросом 1. Мне понравился наш однозначный двойной ответ.
2. @luqui Я понял, что был вопрос 1 после того, как я ответил на вопрос 2, поэтому я сначала пометил ответ как только для Q2, и я начал редактировать, чтобы завершить ответ. Да, ответы «split» выглядели лучше, в некотором эстетическом смысле 🙂
3. Только что я исправил это после ваших подсказок. Но в следующей строке все еще есть одна ошибка:
preorder Empty = []
. Ошибка вE:HaskellUebungsblatt_2_Aufgabe_2_a.hs:8:1: error: Equations for `preorder' have different numbers of arguments E:HaskellUebungsblatt_2_Aufgabe_2_a.hs:8:1-19 E:HaskellUebungsblatt_2_Aufgabe_2_a.hs:9:1-35 | 8 | preorder Empty = [] | ^^^^^^^^^^^^^^^^^^^^... [Finished in 0.5s]
@chi @luqui4. @LeonhardFelix Вам нужно больше круглых скобок:
preorder Branch a l r = ...
это функция, которая принимает 4 аргумента, в то время как то, что вы хотите,preorder (Branch a l r) = ...
. Я соответствующим образом отредактировал свой ответ.5. @chi большое спасибо