在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中,我必须一次又一次为每个Applicative提供一个Monad实例。

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

最佳答案

当前无法实现,尽管如果您更改了现有库以支持此功能,那将是不可能的。打开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或方法定义)将继承这些默认实现。我不确定为什么没有这样做。

关于haskell - 我可以自动实现类吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29414360/

10-10 18:24
查看更多