【问题标题】:Is it possible to write an Alternative instance for Identity a if there's a Monoid for a?如果 a 有 Monoid,是否可以为 Identity a 编写 Alternative 实例?
【发布时间】:2021-08-23 12:00:39
【问题描述】:

我想为Identity 新类型写一个Alternative 实例。骨架并不难:

instance Alternative Identity where
  empty = _
  (<|>) = _

但是,所有类型都无法实现。如果我有一个 a 的 Monoid 实例,那会很容易:

instance Alternative Identity where
  empty = Identity mempty
  (Identity a) <|> (Identity a') = Identity (a <> a')

有没有办法告诉编译器我想定义 Alternative 实例仅适用于内部类型具有 Monoid 实例时?由于a 没有在任何地方提及,我不能只使用约束Monoid a =&gt;

【问题讨论】:

标签: haskell alternative-functor


【解决方案1】:

Alternative 必须为 所有 类型 a 提供 empty,没有任何限制。否则,它不会履行Alternative 合约。

也就是说,如果我们有一个实例Alternative f,我们一定有

empty :: forall a . f a

没有任何进一步的限制。

因此,Identity 不是 Alternative

这是一个已知问题,在许多类似的类型类中都可以找到。例如,许多人会喜欢Functor Set 实例,但这需要

fmap :: (a -> b) -> Set a -> Set b

对于所有类型ab,而上述功能只能在Ord类型上实现。由于我们不能添加约束,所以我们没有得到函子。

不过,可以尝试使用更通用的类型类来解决额外的约束。也许像

class CFunctor c f where
   fmap :: (c a, c b) => (a->b) -> f a -> f b

class CFunctor c f => CApplicative c f where
   empty :: c a => f a
   (<*>) :: (c a, c b, c (a->b)) => f (a->b) -> f a -> f b

但这些不是库中的“标准”。 (我猜在 hackage 上应该有类似于上面的约束类变体的东西。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多