【问题标题】:Binary Tree Fold Functions二叉树折叠函数
【发布时间】:2017-04-04 18:34:10
【问题描述】:

我在 Haskell 中对二叉树的定义如下:

data BTree x = Nil | BNode x (BTree x) (BTree x)

然后我有这个数据类型的折叠定义:

foldB :: (x -> u -> u -> u) -> u -> BTree x -> u
foldB f a Nil = a
foldB f a (BNode x l r) = f x (foldB f a l)(foldB f a r)

所以我希望我可以简单地使这个函数对所有值求和:

sumBFold :: (Num a) => BTree a -> a
sumBFold x = foldB (+) 0 x

但这不起作用,我终其一生都无法弄清楚原因。 我收到的错误消息的有用部分是:

Couldn't match type `a` with `a -> a'
`a' is a rigid type variable bound by the type signature for:
sumBFold :: forall a. Num a => BTree a -> a
Expected type: (a -> a) -> a -> a -> a
Actual type: (a -> a) -> (a -> a) -> a -> a
In the first argument of folB namely `(+)`

【问题讨论】:

  • 你需要传递给foldB的函数需要3个参数,而(+)只需要2个。

标签: haskell binary-tree fold


【解决方案1】:

错误来自尝试使用

(+) :: (Num a) => a -> a -> a

作为带有类型的参数

(x -> u -> u -> u)

如果您开始尝试适应它,请记住 (x -> u -> u -> u)(x -> (u -> (u -> u))) 相同,

x == a
u == a
u -> u == a -> a == a

这是不可能的,错误来自哪里。

考虑以下任何一项。

sumBFold :: (Num a) => BTree a -> a
sumBFold = foldB add3 where add3 x y z = x + y + z
sumBFold = foldB $ \x y z -> x + y + z
sumBFold = foldB ((.) (+) . (+))

【讨论】:

  • 感谢您的明确回答。我还是函数式编程的新手,很容易被类型甩掉
猜你喜欢
  • 1970-01-01
  • 2022-01-04
  • 2013-07-20
  • 2021-05-04
  • 2017-01-03
  • 1970-01-01
  • 2021-09-17
  • 2020-08-12
  • 1970-01-01
相关资源
最近更新 更多