#haskell #recursion #tree #algebraic-data-types #non-exhaustive-patterns
#haskell #рекурсия #дерево #алгебраические типы данных #неисчерпывающие шаблоны
Вопрос:
Я совсем новичок в Haskell и поэтому не очень хорошо знаком с ним.
Следующий метод заключается в измерении размера a MultTree
.
A MultTree
включает Index
узлы, которые содержат два Int
‘s и могут иметь произвольное количество дочерних элементов. Тогда есть также Data
узлы, которые содержат один Int
и не могут иметь дочерних элементов. Итак, что должен определить метод, так это то, какой длины самая длинная «ветвь».
Мой подход до сих пор:
data MultTree a = Index a a [MultTree a] | Data a deriving Show
size :: MultTree a -> Int
size (Index a b []) = 1
size (Index a b [Index c d [e]]) = size (Index c d [e]) 1
Он действительно компилируется, но при попытке его использовать я получаю "non-exhaustive patterns in function size"
. Даже если я не получу эту ошибку, я знаю, что она не будет работать так, как я хотел.
Но почему-то я не могу найти решение этой проблемы.
Я был бы признателен за любую помощь.
Заранее благодарю вас!
Ответ №1:
Вы пишете:
«Итак, метод должен определить, какова длина самой длинной»ветви»».
Это не «размер», обычно его называют «глубиной»:
depth :: MultTree a -> Int
Итак, что мы имеем? a
присутствуют ли значения либо в Index
ветвящихся узлах, либо в Data
конечных узлах:
data MultTree a = Index a a [MultTree a]
| Data a
deriving Show
depth (Data a) = 0 -- or 1, whatever you prefer
depth (Index _ _ trees) =
ну, нам не нужны сами значения, а что касается деревьев, если бы только мы могли найти глубину каждого из них, мы могли бы тогда найти максимум с
let max_depth = maximum [ find_depth t | t <- trees ]
in
max_depth 1
Теперь перейдем к написанию этой find_depth
функции. Его желаемый тип, определяемый тем, как мы его используем, является find_depth :: MultTree a -> Int
. Ну,
(остальное намеренно оставлено пустым)
О, и причина ошибки в том, [e]
что тип обозначает «список значений e
типа»; но в качестве шаблона он обозначает «одноэлементный список с одним значением» — и когда в этом списке более одного значения, такой случай не рассматривается, поэтомуошибка «неисчерпывающие шаблоны», т. Е. Требуется больше шаблонов для покрытия этих случаев, но они отсутствуют.
Аналогично, [Index c d [e]]
поскольку шаблон обозначает «одноэлементный список с одним значением типа MultTree a
, который соответствует шаблону Index c d [e]
, где оба c
и d
являются a
значениями типа, и [e]
представляет собой одноэлементный список с одним значением типа, который определяется MultTree a
типом — т.Е., Опять же, MultTree a
:
data MultTree a = Index a a [MultTree a]
| ...