【问题标题】:What is the fixed point of fix?什么是固定点?
【发布时间】:2016-06-04 00:17:42
【问题描述】:

最近的一位最好匿名的发帖人试图像这样实现阶乘函数:

f :: Int -> Int
f = fix f

这显然效果不太好。但后来我想知道:我可以让它通过类型检查器吗?它的类型会揭示什么?

【问题讨论】:

  • 哇...我没有得到fact ^^ 的部分 - 但感谢更新

标签: haskell recursion fixpoint-combinators


【解决方案1】:

确实,由于多态递归,它会在给定更通用的类型时进行类型检查:

f :: a
f = fix f

通过参数化,我们立即可以看出它一定是底部,根据fix的定义,它一定是无限循环而不是异常。

chi comments,“出于同样的原因,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,此时很明显,第一个参数对于产生结果是无用的。

【讨论】:

  • 有趣。出于同样的原因,f = bar f 将与任何bar :: F a -> a“工作”,其中F a 是任何类型(可能取决于a)。例如。 proj2 :: (a,a) -> a。我实际上认为fix 并没有什么特别之处,它在这里被利用了。
  • 关于fix,这些也类型检查:f3 :: a -> a ; f3 = fix f3f4 :: (a -> a) -> a -> a ; f4 = fix f4。仍然需要多态递归(当然!),但我发现有趣的是,我们的类型比 ::a 更多(我猜是无限多)。
  • @chi,请查看我对您第一条评论的回复。您的第二个也是有效的,但是因为 Haskell 的邪恶 seq 可以区分 const ⊥const (const ⊥) 等,所以最通用的 forall a . a 输入也是最多信息的。
  • 答案中的参数化是什么意思?我不能立即看到它是参数化的底部。
  • @Sibi,forall a . a 类型的东西必须能够为任何a 生成a 类型的东西,而无需任何关于a 的信息。这是不可能的,但对于⊥。
猜你喜欢
  • 2011-11-25
  • 1970-01-01
  • 2023-03-07
  • 2013-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多