Как измерить размер многодерева в Haskell?

#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] 
                | ...