![](/img/trans.png)
[英]What is the type of this function definition "twice f x = f (f x)"
[英]What Justification for the type of f x = f x in Haskell is there?
Haskell给fx = fx
类型为t1 -> t
,但是有人可以解释为什么吗?
并且,任何其他非等效函数是否有可能具有相同的类型?
好的,从函数定义fx = fx
,让我们一步一步看看我们可以推断出f
的类型。
从一个完全未指定的类型变量开始, a
。 我们能推断出更多吗? 是的,我们观察到f
是一个带有一个参数的函数,所以我们可以将a
变成两个未知类型变量之间的函数,我们称之为b -> c
。 无论b
代表什么类型的是参数x
类型, c
代表的任何类型都必须是定义右侧的类型。
我们可以弄清楚右侧的哪些方面? 好吧,我们有f
,它是我们定义的函数的递归引用,因此它的类型仍然是b -> c
,其中两个类型变量与f
的定义相同。 我们还有x
,它是f
定义中的变量,并且有b
类型。 将f
应用于x
类型检查,因为它们共享相同的未知类型b
,结果为c
。
在这一点上,所有东西都在一起,没有其他限制,我们可以使类型变量“正式”,从而产生最终类型的b -> c
,其中两个变量都是Haskell中通常的,隐式普遍量化的类型变量。
换句话说, f
是一个函数,它接受任何类型的参数并返回任何类型的值。 它如何返回任何可能的类型? 它不能,我们可以观察到评估它只产生无限递归。
出于同样的原因,任何具有相同类型的函数在评估时永不返回的意义上都是“等效的”。
更直接的版本是完全删除参数:
foo :: a
foo = foo
......这也是普遍量化的,代表任何类型的价值。 这几乎等同于undefined
。
f x = undefined
具有(alpha)等效类型f :: t -> a
。
如果你很好奇,Haskell的类型系统来自Hindley-Milner 。 非正式地,类型检查器以一切最宽松的类型开始,并统一各种约束,直到剩下的是一致的(或不是)。 在这种情况下,最常见的类型是f :: t1 -> t
,并且没有其他约束。
相比于
f x = f (f x)
由于统一了LHS上f
的参数类型和RHS上外部f
的参数,推断出类型为f :: t -> t
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.