Типы должны соответствовать:
treeFold :: ( b -> a -> b -> b ) -> b -> Tree a -> b
treeToList = treeFold (\xs x ys -> xs ++ (x : ys)) z
-------------------------------------------------------------------
b a b b a b b
--------
b
Поскольку x
и ys
участвуют в одном и том же :
, их типы должны быть совместимы:
(:) :: a -> [a] -> [a]
x :: a
ys :: b
-------------------
b ~ [a]
Таким образом, мыиметь
treeFold :: ( [a] -> a -> [a] -> [a] ) -> [a] -> Tree a->[a]
treeToList = treeFold (\ xs x ys -> xs ++ (x : ys)) z
-------------------------------------------------------------------
[a] a [a] [a] a [a] [a]
--------
[a]
Вывод: последний аргумент z
должен иметь тип [a]
.
Что означает этот аргумент?Как обычно в случае сгибов, каждый «вариант» в определении типа данных имеет соответствующий аргумент для функции сгиба.
Ваше (отсутствующее) определение типа данных:
data Tree a = Node (Tree a) a (Tree a) | Leaf
итип сгиба
treeFold :: ( b -> a -> b -> b ) -> b -> Tree a -> b
, что соответствует " рекурсивным результатам типу хранения"
data TreeF a r = NodeF r a r | LeafF
Таким образом z
- это значение для преобразования каждогоLeaf
до ".
Самый естественный выбор для него это просто []
.На самом деле, единственный выбор, потому что мы ничего не знаем о типе a
(в [a]
).