0

fold(+)0サンプルを実行すると、(+)があまりにも多くの引数に適用されているというエラーが発生します。なんで?

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

あなたの問題は、関数を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 に答える
1

最初のパラメーターとしてtypefoldの関数が必要a -> b -> b -> bです。これは、3 つの引数を取る関数です。(+)一方、引数は 2 つしか取りません。

変更する必要がある場合fold、または別の関数で呼び出す必要がある場合は、何をしようとしているのかによって異なります。

于 2011-02-04T00:28:04.980 に答える