繁体   English   中英

为什么Kleisli不是Monoid的一个例子?

[英]Why isn't Kleisli an instance of Monoid?

如果你想附加两个类型为(a - > mb)的函数,这样你只能得到一个相同类型的函数来追加两个结果,你可以使用Kleisli来做到这一点:

instance (Monad m, Monoid b) => Monoid (Kleisli m a b) where
    mempty = Kleisli (\_ -> return mempty)
    mappend k1 k2 =
        Kleisli g
            where
                g x = do
                    r1 <- runKleisli k1 x
                    r2 <- runKleisli k2 x
                    return (r1 <> r2)

但是,目前Control.Arrow没有定义此类实例。 通常,在Haskell,我怀疑有一个很好的理由,但找不到哪一个。

注意

这个问题是相当类似, 这一个 但是,使用Monoid我没有看到定义实例的方法,例如:

instance (Monad m, Monoid b) => Monoid (a -> m b) where
    [...]

因为已经存在一个实例:

instance Monoid b => Monoid (a -> b) where
    [...]

在图书馆设计业务中,我们在这里面临一个选择点,我们选择在集体政策(或缺乏集体政策)中不完全一致。

Monad (或Applicative )类型构造函数的Monoid实例可以以多种方式出现。 逐点提升始终可用,但我们没有定义

instance (Applicative f, Monoid x) => Monoid (f x) {- not really -} where
  mempty         = pure mempty
  mappend fa fb  = mappend <$> fa <*> fb

请注意, instance Monoid (a -> b)就是这样一个逐点提升,因此只要mb的monoid实例为b上的monoid逐点提升,就会发生(a -> mb)逐点提升。

我们一般不进行逐点提升,不仅因为它会阻止其载体碰巧应用类型的其他Monoid实例,而且因为f的结构通常被认为比x的结构更重要。 一个关键的例子是自由幺半群,更好地称为[x] ,它是[](++)Monoid ,而不是逐点提升。 幺半群结构来自列表包装,而不是来自包装的元素。

我的首选经验法确实优先考虑类型构造函数中固有的幺半群结构优先于点式提升,或类型的特定实例的幺半群结构,如a -> a的组合monoid。 这些可以并且确实得到newtype包装。

关于Monoid (mx)是否应该与MonadPlus m同时存在(和Alternative同样)的争论突破。 我的感觉是唯一好的MonadPlus实例是Monoid实例的副本,但其他实例不同。 尽管如此,图书馆在这个问题上仍然不一致,特别是在这个问题上(很多读者都会看到我的这个古老的虫子来了)......

... Maybe的monoid实例,它忽略了我们经常使用Maybe来模拟可能的失败的事实,而是观察到在一个额外的元素中使用相同的数据类型的想法可以用来给半群提供一个中性元素,如果它还没有。 这两种结构产生了同构类型,但它们在概念上并不相同。 编辑更糟糕的是,这种想法是实现得很笨拙,给人实例Monoid约束,当只有一个Semigroup是必要的。我想看到的Semigroup -extends-TO- Monoid的想法实现的,而不是 Maybe 。)

特别是回到Kleisli ,我们有三个明显的候选实例:

  1. Monoid (Kleisli maa)带有return和Kleisli组成
  2. MonadPlus m => Monoid (Kleisli mab)提升mzeromplus逐点->
  3. Monoid b => Monoid (Kleisli mab)升降的幺半结构bm然后->

我希望没有做出任何选择,只是因为不清楚做出哪个选择。 我犹豫不决,但我的投票将是2,优先考虑来自Kleisli ma的结构来自b的结构。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM