gpt4 book ai didi

haskell - Ed Kmett 的递归方案包中的 Fix、Mu 和 Nu 有什么区别

转载 作者:行者123 更新时间:2023-12-02 09:19:47 25 4
gpt4 key购买 nike

在 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 中,这些是同构的,并且是表示同一类型的不同方式。如果你假装 Haskell 没有任意递归,这些类型之间的区别就会变得更有趣:Mu ff 的最小(初始)不动点,而 Nu f 是其最大(终端)不动点。

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

举一个具体的例子,假设您无法编写递归值。 Mu Maybe 的居民,即值 ::forall r。 (也许 r -> r) -> r 是自然数,{0, 1, 2, ...}; Nu Maybe 的居民,即值 ::exists x。 (x, x -> Maybe x) 是余自然数 {0, 1, 2, ..., ∞}。考虑这些类型的可能值,看看为什么 Nu Maybe 有一个额外的居民。

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

  • zeroMu::Mu MaybesuccMu::Mu Maybe -> Mu Maybe
  • zeroNu::Nu MaybesuccNu::Nu Maybe -> Nu MaybeinftyNu::Nu Maybe
  • muTofix::Mu f -> 修复 ffixToNu::修复 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 -> 修复 ffixToMu::修复 f -> Mu f

Mu f 是最小不动点,Nu f 是最大不动点,所以写一个函数 ::Mu f -> Nu f 很容易,但是写一个函数 ::Nu f -> Mu f 就很难了;这就像逆流游泳。

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

关于haskell - Ed Kmett 的递归方案包中的 Fix、Mu 和 Nu 有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45580858/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com