0

运行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

参见:折叠

4

2 回答 2

1

fold需要一个类型的函数a -> b -> b -> b作为其第一个参数,即一个接受三个参数的函数。(+)另一方面,只需要两个参数。

是否应该更改或者fold是否需要使用不同的函数调用它取决于您到底要做什么。

于 2011-02-04T00:28:04.980 回答
1

您的问题是您将该函数应用于 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)
于 2011-02-04T03:13:05.507 回答