Слишком много аргументов в обобщенной версии функции сгиба для BST - PullRequest
0 голосов
/ 04 февраля 2011

Запуск fold (+) 0 sample выдает ошибку об (+) применении к слишком большому количеству аргументов Почему?

data(Ord a, Show a, Read  a) => BST a = Void | Node {
    val :: a,
    left, right :: BST a
} deriving (Eq,  Ord,  Read,  Show)

sample = Node 5 (Node 3 Void Void) (Node 10 Void Void)

fold :: (Read a, Show a, Ord a) => (a -> b -> b ->  b) -> b -> BST a -> b
fold _ z Void         = z
fold f z (Node x l r) = f x (fold f z l) (fold f z r)
Occurs check: cannot construct the infinite type: a = a -> a
Probable cause: `+' is applied to too many arguments
In the first argument of `fold'', namely `(+)'
In the expression: fold' (+) 0 sample

См. Также: сгиб

Ответы [ 2 ]

1 голос
/ 04 февраля 2011

Ваша проблема в том, что вы применяете функцию к 3 аргументам. Первый параметр в сигнатуре типа говорит сам за себя.

fold :: (a -> b -> b -> b) -> b -> BST a -> b
fold f z (Node x l r) = f x (fold f z l) (fold f z r)

(+) принимает только 2 аргумента, но когда вы передаете его, он пытается оценить это:

(+) x (fold (+) z l) (fold (+) z r) -- 3 arguments! =P

Вы, вероятно, хотите сложить с помощью двоичной функции (a -> a -> a). Предположим, вы хотите использовать (+). Вы хотите, чтобы результат был таким:

fold f z (Node x l r) = x + (fold f z l) + (fold f z r)

Отсюда легко обобщить: просто замените + на инфиксированный f

fold f z (Node x l r) :: (a -> a -> a) -> a -> BST a -> a
fold f z (Node x l r) = x `f` (fold f z l) `f` (fold f z r)
1 голос
/ 04 февраля 2011

Вашему fold требуется функция типа a -> b -> b -> b в качестве первого параметра, то есть функция, которая принимает три аргумента. (+), с другой стороны, принимает только два аргумента.

Если fold нужно изменить или если вам нужно вызвать его с другой функцией, зависит от того, что именно вы пытаетесь сделать.

...