【问题标题】:What is the difference between Fix, Mu and Nu in Ed Kmett's recursion scheme packageEd Kmett的递归方案包中的Fix、Mu和Nu有什么区别
【发布时间】:2018-01-16 18:19:44
【问题描述】:

在 Ed Kmett 的 recursion-scheme 包中,有三个声明:

newtype Fix f = Fix (f (Fix f))

newtype Mu f = Mu (forall a. (f a -> a) -> a)

data Nu f where 
  Nu :: (a -> f a) -> a -> Nu f

这三种数据类型有什么区别?

【问题讨论】:

  • 我不太了解理论,但我认为对于更可靠的语言,Mu 是最小不动点,Nu 是最大不动点。在 Haskell 中,这三个都应该是等价的(我相信)。请注意,对于 Muana 对于 Nu 实现 cata 非常容易。

标签: haskell recursive-datastructures recursion-schemes fixpoint-combinators


【解决方案1】:

Mu 将递归类型表示为其折叠,Nu 将其表示为展开。在 Haskell 中,这些是同构的,并且是表示同一类型的不同方式。如果你假设 Haskell 没有任意递归,那么这些类型之间的区别会变得更有趣:Mu ff 的最小(初始)不动点,Nu f 是其最大(终端)不动点。

f 的不动点是T 类型,是Tf T 之间的同构,即一对反函数in :: f T -> Tout :: T -> f TFix 类型只是使用 Haskell 内置的类型递归来直接声明同构。但是您可以同时为MuNu 实现输入/输出。

举个具体的例子,假装你不能写递归值。 Mu Maybe 的居民,即值 :: forall r. (Maybe r -> r) -> r,是自然人,{0, 1, 2, ...}; Nu Maybe 的居民,即 :: exists x. (x, x -> Maybe x) 的值,是 conaturals {0, 1, 2, ..., ∞}。想想这些类型的可能值,看看为什么Nu Maybe 有一个额外的居民。

如果您想对这些类型有一些直觉,那么在不递归的情况下实现以下内容可能是一个有趣的练习(大致按难度递增的顺序):

  • zeroMu :: Mu Maybe, succMu :: Mu Maybe -> Mu Maybe
  • zeroNu :: Nu Maybe, succNu :: Nu Maybe -> Nu Maybe, inftyNu :: Nu Maybe
  • muTofix :: Mu f -> Fix f, fixToNu :: Fix f -> Nu f
  • inMu :: f (Mu f) -> Mu f, outMu :: Mu f -> f (Mu f)
  • inNu :: f (Nu f) -> Nu f, outNu :: Nu f -> f (Nu f)

您也可以尝试实现这些,但它们需要递归:

  • nuToFix :: Nu f -> Fix f, fixToMu :: Fix f -> Mu f

Mu f是最小不动点,Nu f是最大不动点,所以写函数:: Mu f -> Nu f很容易,写函数:: Nu f -> Mu f很难;就像逆流而上。

(有一次我打算对这些类型写一个更详细的解释,但对于这种格式来说可能有点太长了。)

【讨论】:

  • 很好的解释,谢谢!是否有资料(文章/论文/书籍)可以更详细地解释它?例如,术语级别固定点的类似物以及为什么 Nu(作为递归类型的表示)在类型级别是最小固定点。 LFP 和初始代数之间以及 GFP 和终末代数之间也存在重要联系。
  • 我确定我遗漏了一些东西,但Nu Maybe 似乎有更多的居民——至少有许多是 Haskell 乐于进行类型检查的。例如,Nu Just []Nu Just "abcd"Nu (const Nothing) 42 似乎都输入正确。我做错了什么?
  • 等等。自然数?那是一回事吗?
  • Sergey Cherepanov:我不知道有什么副手,虽然here 是使用参数的初始证明。初始代数和初始不动点之间的联系有时被称为 Lambek 引理。 B. Mehta:同 id :: forall a。 a -> a 无法区分不同的输入,外界无法区分 Nu Just [] 和 Nu Just 0。 paulotorrens:至少是这种类型的惯用名称,naturals 的单点紧缩,出于这个原因。
  • 感谢您的有趣练习!如果有人感兴趣,我在这里上传了我的答案:gist.github.com/inamiy/7488380da6001cb0f778b59d9f7230cd
猜你喜欢
  • 2017-05-04
  • 2020-09-20
  • 2022-11-29
  • 2013-11-16
  • 2018-05-06
  • 2020-07-19
  • 2018-08-03
  • 2016-02-01
  • 1970-01-01
相关资源
最近更新 更多