首页 > 解决方案 > Haskell:无法构造无限类型:t ~ t -> t

问题描述

我写了一个函数,它计算加泰罗尼亚数字,但它不能编译。我收到此错误消息:

• Occurs check: cannot construct the infinite type: t ~ t -> t Relevant bindings include catalanNum :: t (bound at CatNum.hs:1:1)

这是我的代码:

catalanNum 0 = 1
catalanNum n =  div(2 *(catalanNum * (n-1)) * (2 * (n-1) + 1))(n + 1)

我怎样才能消除这个错误?

标签: haskell

解决方案


catalanNum 0 = 1
catalanNum n =  div(2 *(catalanNum * (n-1)) * (2 * (n-1) + 1))(n + 2)

您的代码中的问题在这里,

catalanNum * (n-1)
           ^

您正在将一个函数与一个整数相乘。你可能想写,

catalanNum (n-1)

更重要的是,您应该知道如何找到此类错误。即使您不理解错误消息,也应该做的一件事是减少有问题的表达。原来的表达是,

catalanNum n =  div (2 *(catalanNum * (n-1)) * (2 * (n-1) + 1)) (n + 2)

需要两个参数,div原则上一个是有问题的,它很可能是第一个,因为第二个相当简单。所以修剪一下。

catalanNum n =  2 *(catalanNum * (n-1)) * (2 * (n-1) + 1)

您可以将其视为三个因素相乘,

2 
catalanNum * (n-1)
2 * (n-1) + 1

看他们。如果您没有看到错误,请尝试一下。第一个无关紧要。最后的作品,

catalanNum n = 2 * (n-1) + 1

中间没有,

catalanNum n = catalanNum * (n-1)

这现在应该是比较明显的了。


修剪表达式后,如果仍然看不到错误的来源,请添加类型签名catalanNum :: Int -> Int。然后错误变为,

Couldn't match expected type ‘Int’ with actual type ‘Int -> Int’

您希望catalanNum成为 aInt以便将其相乘,但它的类型为Int -> Int

关于原来的错误,

Occurs check: cannot construct the infinite type: t ~ t -> t

如果没有类型签名,类型推断算法得出的结论是,您有一个表达式,其类型必须同时为 somett->t(written t ~ t->t)。但它会有无限的长度和深度,因为你也会得出结论,

 t ~ t->t
 t ~ t->t->t
 t ~ t->t->t->t 
 ...

 t ~ t->t
 t ~ (t->t)->t
 t ~ ((t->t)->t)->t
 ...

以及两者的组合。


推荐阅读