【问题标题】:Is there a non-identity monad morphism M ~> M that is monadically natural in M?在 M 中是否存在单子自然的非同一性单子态射 M ~> M?
【发布时间】:2020-08-10 03:42:55
【问题描述】:

众所周知,类型签名a -> a 的自然变换必须是恒等函数。这来自米田引理,但也可以直接推导出来。这个问题要求相同的属性,但要求单子态射而不是自然变换。

考虑单子之间的单子态射M ~> N。 (这些是自然变换M a -> N a,它保留了两边的单子操作。这些变换是单子类别中的态射。)我们可以问是否存在一个单子态射e :: (Monad m) => m a -> m a,它对每个单子都以相同的方式工作m。换句话说,一个单子态射e 在单子类型参数m 中必须是单子自然的。

单子自然法则规定,对于任意两个单子 M 和 N 之间的任何单子态射 f: M a -> N a,我们必须有 f . e = e . f 和合适的类型参数。

问题是,我们能否证明任何这样的e 必须是一个恒等函数,或者是否存在定义为的非恒等单态射e 的反例

  e :: (Monad m) => m a -> m a
  e ma = ...

定义此类e 的一次失败尝试是:

 e ma = do
         _ <- ma
         x <- ma
         return x

另一个失败的尝试是

 e ma = do
         x <- ma
         _ <- ma
         return x

这两种尝试都有正确的类型签名,但不符合单子态射定律。

似乎米田引理不能应用于这种情况,因为没有单子态射Unit ~&gt; M 其中Unit 是单元单子。我也无法直接找到任何证据。

【问题讨论】:

    标签: haskell monads category-theory


    【解决方案1】:

    我想你已经用尽了所有有趣的可能性。我们可能定义的任何Monad m =&gt; m a -&gt; m a 函数都不可避免地看起来像这样:

    e :: forall m a. Monad m => m a -> m a
    e u = u >>= k
        where
        k :: a -> m a
        k = _
    

    特别是,如果k = returne = id。对于e 不是idk 必须以不平凡的方式使用u(例如,k = const uk = flip fmap u . const 等于您的两次尝试)。但是,在这种情况下,u 效果将被复制,导致e 无法成为许多单子m 选择的单子态射。既然如此,monad中唯一完全多态的monad态射是id


    让我们更明确地论证。

    为了清楚起见,我暂时切换到join/return/fmap 演示文稿。我们要实现:

    e :: forall m a. Monad m => m a -> m a
    e u = _
    

    我们可以用什么填充右侧?最明显的选择是u。就其本身而言,这意味着e = id,看起来并不有趣。但是,由于我们还有joinreturnfmap,因此可以选择以u 作为基本情况进行归纳推理。假设我们有一些v :: m a,使用我们手头的方法构建。除了v本身,我们还有以下几种可能:

    1. join (return v),即v,因此不会告诉我们任何新信息;

    2. join (fmap return v),也就是v;和

    3. join (fmap (\x -&gt; fmap (f x) w) v),还有一些根据我们的规则构建的w :: m a,还有一些f :: a -&gt; a -&gt; a。 (将m 层添加到f 的类型中,如a -&gt; a -&gt; m a 和额外的joins 以删除它们不会导致任何地方,因为我们必须显示这些层的出处,以及最终会减少到其他情况。)

    唯一有趣的案例是#3。此时,我会走捷径:

    join (fmap (\x -> fmap (f x) w) v)
        = v >>= \x -> fmap (f x) w
        = f <$> v <*> w
    

    因此,任何非u 右手边都可以用f &lt;$&gt; v &lt;*&gt; w 的形式表示,vw 要么是u,要么是这种模式的进一步迭代,最终达到u s 在叶子上。然而,这类应用表达式具有规范形式,通过使用应用法则将(&lt;*&gt;) 的所有用法重新关联到左侧,在这种情况下必须看起来像这样......

    c <$> u <*> ... <*> u
    

    ... 省略号代表零次或多次出现的u,由&lt;*&gt; 分隔,c 是适当数量的a -&gt; ... -&gt; a -&gt; a 函数。由于a 是完全多态的,所以c 必须通过参数化,成为一些类似于const 的函数,它选择它的一个参数。既然如此,任何这样的表达式都可以重写为(&lt;*)(*&gt;)...

    u *> ... <* u
    

    ...省略号代表零次或多次出现的u,由*&gt;&lt;* 分隔,&lt;* 右侧没有*&gt;

    回到开头,所有非id 候选实现必须如下所示:

    e u = u *> ... <* u
    

    我们还希望e 是一个单子态射。因此,它也必须是一个应用态射。特别是:

    -- (*>) = (>>) = \u v -> u >>= \_ -> v
    e (u *> v) = e u *> e v
    

    即:

    (u *> v) *> ... <* (u >* v) = (u *> ... <* u) *> (v *> ... <* v)
    

    我们现在有了一个明确的反例路径。如果我们使用应用法则将两边都转换为规范形式,我们将(仍然)在左侧得到交错的us 和vs,而所有vs 毕竟是@987654390 @s 在右侧。这意味着该属性不适用于 IOStateWriter 之类的单子,无论 (*&gt;)(&lt;*) 中有多少 e,或者究竟是哪些值被 @ 987654397@-like 功能在任一侧。快速演示:

    GHCi> e u = u *> u <* u  -- Canonical form: const const <$> u <*> u <*> u
    GHCi> e (print 1 *> print 2)
    1
    2
    1
    2
    1
    2
    GHCi> e (print 1) *> e (print 2)
    1
    1
    1
    2
    2
    2
    

    【讨论】:

    • 我找不到足够严格的证明。我们如何证明u 的效果将必然重复,除非e = id? (我们也可以写e u = do _ &lt;- u; _ &lt;- u; _ &lt;- u; u 并进一步组合u-效果。)我们如何在数学上描述“一元值p :: m a 具有从u :: m a 复制的多个效果?然后,我们如何证明重复的(三倍等)u-效果必然导致违反单子态射定律?
    • @winitzki 我已经更明确地写下了我的论点。鉴于我观察到的失败更多地与效果的交换性有关,我在答案的原始修订中肯定提出的一个想法是提到幂等性。
    • 这很有趣。我将不得不考虑更多。我们如何证明只有一种方法可以实现不平凡的e u,即使用您所描述的u *&gt; ... &lt;* u 形式的某种表达式?为什么我们不能找到fmapreturnjoin 的其他巧妙而复杂的组合,从而得到其他东西?考虑应用态射也是一个很好的举措。证明应用态射的类比性质可能比单子态射更容易。 (唯一应用自然的应用态射是恒等态射?)
    • @winitzki (1) 虽然有一个更清晰的演示文稿会很好(我仍在考虑),但我相信我的三个案例是详尽无遗的。只有join _ 可以导致非id 结果,而#3 是唯一不会导致id 或无限回归的方法。 (2)在Applicative:非正式地,如果你唯一的Kleisli箭头是return,你并没有使用Monad带来的额外力量,所以你还不如和Applicative一起工作。 (3) 是的,类比性质适用于应用态射。我的论证部分以规范形式开始,它是自包含的,应该足以作为证据。
    • 如果我们有一个单子自然的单子态射,我们也会有一个应用自然的应用态射。我认为证明不存在这样的应用态射可能更容易。
    猜你喜欢
    • 2021-10-15
    • 1970-01-01
    • 2018-12-11
    • 2017-03-07
    • 1970-01-01
    • 2015-04-17
    • 2018-10-21
    • 2016-04-21
    • 1970-01-01
    相关资源
    最近更新 更多