运行我的foldTree函数时出错

时间:2013-05-07 00:22:51

标签: haskell fold

我想写一个treeFold函数,它接受:'a - >类型的函数f b - > a,类型a的值x,名为t的树B,返回类型a的值。通过执行树的有序遍历来计算返回值,通过x传递部分结果。 这是我的代码:

import Control.Exception
import Control.Monad
import Control.DeepSeq
import qualified Data.List as List
import Test.HUnit

data Tree a  =  Empty
             |  Node a (Tree a) (Tree a)
             deriving (Show, Eq)



insertTree :: ( Ord a, Show a ) => Tree a -> a -> Tree a
insertTree Empty x  =  Node x Empty Empty
insertTree ( Node v tLeft tRight ) x
    | x == v = Node v tLeft tRight
    | x < v = Node v (insertTree tLeft x) tRight
    | x > v = Node v tLeft (insertTree tRight x)


createTree :: ( Ord a, Show a ) => [ a ] -> Tree a
createTree = foldl insertTree Empty

intTree = createTree [9,7,2,8,6,0,5,3,1]

listTree = createTree ( List.permutations [ 0 .. 3 ] )

strTree = createTree [ "hello"
                     , "world"
                     , "lorem"
                     , "ipsum"
                     , "dolor"
                     , "sit"
                     , "amet"
                     ]
treeFold :: (a -> b -> b -> b) -> b -> Tree a -> b
treeFold f z Empty = z
treeFold f z (Node v l r) = f v (subfold l) (subfold r)
    where subfold = foldTree f z

但是当我运行代码时,我得到了“无法匹配的类型错误”。我想知道如何解决这个问题?例如:主要&gt; treeFold(+)10 intTree,而不是获得Main&gt; 51,我得到的不能匹配类型错误。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

在你的功能中

treeFold :: (a -> b -> b -> b) -> b -> Tree a -> b
treeFold f z Empty = z
treeFold f z (Node v l r) = f v (subfold l) (subfold r)
    where subfold = foldTree f z

您对三个值使用fv(subfold l)(subfold r)。这就是您的类型签名需要f来获取三个参数的原因。

在我看来,你最好两次使用两个参数f,一次合并v(subfold l),另一个合并{{1} }}:

(subfold r)

这确实意味着,如果我们假设treeFold f z Empty = z treeFold f z (Node v l r) = f (f v (subfold l)) (subfold r) where subfold = treeFold f z ,那么f :: a -> b -> c因为subfold l :: b,而且f v (subfold l)因为它是从subfold l :: c返回的。因此,treeFoldc属于同一类型(b)和c ~ b。这被用作第一个f v (subfold l) :: b的第一个参数,所以也f。因此对于这个新的use-f-two版本,

a ~ b