我有一个小的haskell代码,它实现了二叉树。我想在树上应用折叠功能。这是代码 -
data Btree a = Tip a | Bin (Btree a) (Btree a) deriving Show
foldbtree :: (a->a->a) -> Btree a-> a
foldbtree f (Tip x) = x
foldbtree f (Bin t1 t2) = (foldbtree f t1) f (foldbtree f t2)
但是我收到了编译错误 -
Occurs check: cannot construct the infinite type:
t2 = t0 -> t1 -> t2
In the return type of a call of `foldbtree'
Probable cause: `foldbtree' is applied to too many arguments
In the expression: (foldbtree f t1) f (foldbtree f t2)
In an equation for `foldbtree':
foldbtree f (Bin t1 t2) = (foldbtree f t1) f (foldbtree f t2)
bird_exercise.hs:206:47:
Occurs check: cannot construct the infinite type:
t1 = t0 -> t1 -> t2
In the return type of a call of `foldbtree'
Probable cause: `foldbtree' is applied to too few arguments
In the fourth argument of `foldbtree', namely `(foldbtree f t2)'
In the expression: (foldbtree f t1) f (foldbtree f t2)
请帮我解决这个问题。谢谢。
答案 0 :(得分:5)
在最后一种情况下你需要的是:
foldbtree f (Bin t1 t2) = f (foldbtree f t1) (foldbtree f t2)
答案 1 :(得分:3)
事实上,你应该"作弊"让GHC使用Foldable
扩展名自动为您导出数据类型的DeriveFoldable
实例:
{-# LANGUAGE DeriveFoldable #-}
module XXX where
import Data.Foldable (Foldable, foldMap)
import Data.Monoid (Sum(..))
data Btree a = Tip a | Bin (Btree a) (Btree a) deriving (Show, Foldable)
sumTips :: Btree Int -> Int
sumTips = getSum . foldMap Sum
(相关位是.hs文件顶部的{-# LANGUAGE DeriveFoldable #-}
pragma和数据类型定义中的deriving (..., Foldable, ...)
子句。)fold
,foldMap
,来自编译器派生的Btree
Foldable
实例的{几乎肯定是你想要的那些。在您进行此操作时,您可能还希望派生Functor
和Traversable
个实例,这与Foldable
完全相同。如果您愿意,可以通过cabal或命令行传递DeriveXXX
pragma,尽管我喜欢per-file pragma的特殊性。