最近的一张最好匿名的海报试图实现这样的阶乘函数:
f :: Int -> Int
f = fix f
这显然效果不太好。但后来我想知道:我可以让它通过类型检查器吗?它的类型会揭示什么?
最近的一张最好匿名的海报试图实现这样的阶乘函数:
f :: Int -> Int
f = fix f
这显然效果不太好。但后来我想知道:我可以让它通过类型检查器吗?它的类型会揭示什么?
实际上,由于多态递归,它会在给定更通用的类型时进行类型检查:
f :: a
f = fix f
通过参数化,我们立即可以看出它一定是底部,并且根据 的定义fix
,它一定是无限循环而不是异常。
chi评论说,“出于同样的原因,任何类型的任何地方都f = bar f
将‘工作’ (可能取决于)”。定义如下所示:bar :: F a -> a
F a
a
foo :: forall f a .
(forall b . f b -> b) -> a
foo g = g (foo g)
同样,类型签名在参数上是虚假的,因为我可以选择,例如,f ~ Const Void
在这一点上,很明显第一个参数对于产生结果是无用的。