在haskell中的二叉树上应用FOLD

时间:2013-11-19 17:05:24

标签: haskell functional-programming binary-tree

我有一个小的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)

请帮我解决这个问题。谢谢。

2 个答案:

答案 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, ...)子句。)foldfoldMap,来自编译器派生的Btree Foldable实例的{几乎肯定是你想要的那些。在您进行此操作时,您可能还希望派生FunctorTraversable个实例,这与Foldable完全相同。如果您愿意,可以通过cabal或命令行传递DeriveXXX pragma,尽管我喜欢per-file pragma的特殊性。