我可以自动实施课程吗?

在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实例。

是否有可能避免这种重复的工作?


目前还不可能,但如果您改变了现有的库来支持这个功能,那就不可能了。 打开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或方法定义)将继承这些默认实现。 我不知道为什么这没有完成。


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

如果你想,有个WrappedMonadControl.Applicative ,它提供了所有明显的情况下,用newtype包装,但使用WrapMonadunwrapMonad所有的时间是不是有吸引力无论是。

链接地址: http://www.djcxy.com/p/33221.html

上一篇: Can I automatically implement classes?

下一篇: To what extent are Applicative/Monad instances uniquely determined?