2016-03-03 40 views
0

好吧,所以我在Haskell编程方面比较新,并且在处理函数以预先从树中返回数据时,我遇到了这个错误。无法构造无限类型c = [c]

代码:

preorder ::(Show a, Show b) => (a -> c) -> (b -> c) -> Tree a b -> [c] 
preorder x y (Leaf n) = x n 
preorder x y (Branch b ltree rtree) = (y b) ++ (preorder x y ltree) ++ (preorder x y rtree) 

第17行:

preorder x y (Leaf n) = x n 

错误消息:

A3.hs:17:0: 
    Occurs check: cannot construct the infinite type: c = [c] 
    When generalising the type(s) for `preorder' 

,我不知道如果这看起来怪异的人,但对于这个给出的参数代码是为了这个功能采取其他2个功能,将树的元素转换为可用类型。第一个功能是获取树的叶子并将其隐藏,而第二个功能是获取树枝并将其转换,然后构建一个列表。这是想到解决这个问题的第一个尝试。

+0

你调试这种类型的东西的方式通常是输入漏洞 - 你知道结果必须以某种方式涉及'x'和'n',所以你写了你写的东西,但是编译器告诉你你错了。所以你写'preorder x y(Leaf n)= _helpMe(x n)',并用类型:c - > [c]'吐出'Found hole \'_helpMe'。现在仍然有许多类型为'c - > [c]'的函数......但'(:[])'在这里当然是一个明显的选择。 – user2407038

回答

3

根据您所在行的preorder,x :: a -> c的申报类型。即表示x n :: c。但是,返回值preorder被宣布为[c]。这意味着x n :: [c]。第17行应为

preorder x y (Leaf n) = [x n] 

也就是说,叶的返回值必须是可以连接到其他值的单例列表。出于同样的原因,第18行需要阅读

preorder x y (Branch b ltree rtree) = [(y b)] ++ (preorder x y ltree) ++ (preorder x y rtree) 

因为y :: b -> c意味着(y b) :: c,不[c],将需要为++操作。