我可以自动实现类吗?

Can I automatically implement classes?

在 Scalaz 中,每个 Monad 实例自动成为 Applicative 的实例。

implicit val listInstance = new Monad[List] {
  def point[A](a: => A) = List(a)
  def bind[A, B](fa: List[A])(f: A => List[B]) = fa flatMap f
}

List(2) <*> List((x: Int) => x + 1) // Works!

另一个例子:Arrow自动是Profunctor

但是,在 Haskell 中,我必须一次又一次地为每个 Monad 提供一个 Applicative 的实例。

是否可以避免这种重复性工作?

当有两个地方可以派生 Applicative 实例时,问题就来了。例如,假设 m 是类型 a b,其中 Arrow a。然后从这个定义中也有一个明显的 Applicative 实例。编译器应该使用哪一个?当然,结果应该是一样的,但是 Haskell 无法检查这一点。通过让我们写出实例,Haskell 至少迫使我们考虑定义的一致性。

如果需要,Control.Applicative 中有 WrappedMonad class,它为所有明显的实例提供了 newtype 包装器,但使用 WrapMonad而且 unwrapMonad 一直都没有那么有吸引力。

目前不可能,但如果您更改现有库以支持它,则可以。打开 DefaultSignatures 会让你写

class Applicative f where
    pure :: a -> f a
    (<*>) :: f (a -> b) -> f a -> f b

    default pure :: Monad f => a -> f a
    default (<*>) :: Monad f => f (a -> b) -> f a -> f b
    pure = return
    (<*>) = ap

然后一旦您实现了 instance Monad M where {- ... -},一个简单的 instance Applicative M(没有 where 或方法定义)将继承这些默认实现。我不确定为什么没有这样做。