我正在编写一种不带类型的语言,这意味着我需要推断函数调用的返回类型以进行类型检查。但是,当有人编写递归函数时,类型检查器会陷入无限递归,尝试推断函数体内部函数调用的类型。
类型检查器执行以下操作:
1. 推断函数调用实际参数的类型。 2. 创建实际参数类型到形式参数的映射。 3. 使用映射在函数体中使用的参数上注释类型。 4. 推断并返回函数体的返回类型。
步骤4尝试推断函数体内部函数调用的类型,该函数调用再次调用相同的类型检查器函数,从而导致无限递归。
下面是一个给我带来问题的递归函数示例:
如何避免无限递归循环的问题?有没有一种方法可以推断递归函数调用的类型而不必再次进入函数体内?或者有一种从上下文中推断类型的简洁方式吗?
我知道添加函数类型注释可能是一个简单的解决方案,这样问题就很容易解决了,但在这样做之前,我想知道是否有一种方法可以在不使用这种方法的情况下解决这个问题。
我还希望解决方案适用于相互递归的情况。
最初的回答:如何在无需添加类型注释的情况下避免无限递归循环?是否有一种从上下文中推断递归函数调用类型的简便方式?此外,如何处理相互递归的情况?
类型检查器执行以下操作:
1. 推断函数调用实际参数的类型。 2. 创建实际参数类型到形式参数的映射。 3. 使用映射在函数体中使用的参数上注释类型。 4. 推断并返回函数体的返回类型。
步骤4尝试推断函数体内部函数调用的类型,该函数调用再次调用相同的类型检查器函数,从而导致无限递归。
下面是一个给我带来问题的递归函数示例:
function factorial(n) = n<1 ? 1 : n*factorial(n-1); // Function definition.
...
assert 24 == factorial(4); // Function call expression usage example.
如何避免无限递归循环的问题?有没有一种方法可以推断递归函数调用的类型而不必再次进入函数体内?或者有一种从上下文中推断类型的简洁方式吗?
我知道添加函数类型注释可能是一个简单的解决方案,这样问题就很容易解决了,但在这样做之前,我想知道是否有一种方法可以在不使用这种方法的情况下解决这个问题。
我还希望解决方案适用于相互递归的情况。
最初的回答:如何在无需添加类型注释的情况下避免无限递归循环?是否有一种从上下文中推断递归函数调用类型的简便方式?此外,如何处理相互递归的情况?
factorial
的类型为T
,然后继续。我们知道T
是一个函数。接下来,我们看到该函数需要一个参数,因此我们将T
更新为“一个参数的函数”。然后我们发现,在n < 1
的情况下,它返回1
。因此,T
必须是“返回整数的一个参数函数”。现在当我们查看n*factorial(n-1)
时,我们现在知道n
被乘以一个整数,等等。 - Kaz