Haskell中f x = f x类型的理由是什么?

时间:2011-01-31 01:55:00

标签: haskell functional-programming

Haskell给f x = f x类型t1 -> t,但有人可以解释原因吗?

并且,任何其他非等效函数是否可能具有相同的类型?

2 个答案:

答案 0 :(得分:16)

好的,从功能定义f x = f x开始,让我们一步一步看看我们可以推断出f的类型。

从完全未指定的类型变量a开始。我们能推断出更多吗?是的,我们观察到f是一个带有一个参数的函数,因此我们可以将a更改为两个未知类型变量之间的函数,我们将其称为b -> cb所代表的类型是参数x的类型,c所代表的类型必须是定义右侧的类型。

我们可以弄清楚右侧的哪些方面?好吧,我们有f,它是我们定义的函数的递归引用,因此它的类型仍然是b -> c,其中两个类型变量与{{1}的定义相同}。我们还有f,它是x定义中的变量,其类型为f。将b应用于f类型检查,因为它们共享相同的未知类型x,结果为b

此时所有东西都在一起,没有其他限制,我们可以使类型变量“正式”,从而产生最终类型c,其中两个变量都是Haskell中通常的,隐式普遍量化的类型变量

换句话说,b -> c是一个函数,它接受任何类型的参数并返回任何类型的值。它如何返回任何可能的类型?它不能,我们可以观察到它的评估只会产生无限的递归。

出于同样的原因,任何具有相同类型的函数在评估时永远不会返回“等效”。

更直接的版本是完全删除参数:

f

......这也是普遍量化的,代表任何类型的价值。这几乎相当于foo :: a foo = foo

答案 1 :(得分:7)

f x = undefined

具有(alpha)等效类型f :: t -> a


如果你很好奇,Haskell的类型系统来自Hindley–Milner。非正式地,类型检查器以一切最宽松的类型开始,并统一各种约束,直到剩下的是一致的(或不是)。在这种情况下,最常见的类型是f :: t1 -> t,并且没有其他约束。

比较
f x = f (f x)
由于统一了LHS上f :: t -> t的参数类型和RHS上外部f的参数,

推断出类型f