【问题标题】:Cannot Construct The infinite type c = [c]无法构造无限类型 c = [c]
【发布时间】:2016-03-03 12:47:16
【问题描述】:

好的,所以我对 Haskell 编程比较陌生,在处理从树中预排序返回数据的函数时,我遇到了这个错误。

代码:

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'

我不知道这对人们来说是否看起来很奇怪,但是为这段代码提供的参数是为了让这个函数接受另外两个函数,将树的元素转换为可用的类型。第一个函数是获取树的一个叶子并对其进行转换,而第二个函数是获取一个分支并对其进行转换,然后构造一个列表。这是解决这个问题的第一次尝试。

【问题讨论】:

  • 你调试这种类型的东西的方式通常是使用类型孔——你知道结果必须以某种方式涉及xn,所以你写你写的,但是编译器告诉你错了。那么你写preorder x y (Leaf n) = _helpMe (x n),它就会输出Found hole `_helpMe' with type: c -> [c]。现在还有很多c -> [c]类型的函数……但是(:[])在这里肯定是一个明显的选择。

标签: haskell types infinite


【解决方案1】:

根据preorder 的声明类型,x :: a -> c 在您的第 17 行。这意味着 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]++ 运算符将需要它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    相关资源
    最近更新 更多