是否有可能隐式地传递多个类型参数[Monoid [A [B]]。mappend?

时间:2014-05-23 06:30:40

标签: scala

假设我想使用implicitly来简化代码的外观,并且我正在编写一个需要为其中一个参数使用Monoid实例的函数,但是monoid是在容器类型上,例如A[B]。例如:

  trait Monoid[A] {
    def mappend(a1: A, a2: A): A
    def mzero: A
  }

  implicit def futureOfListMonoid[A] = new Monoid[Future[List[A]]] {
    def mappend(a1: Future[List[A]], a2: Future[List[A]]) = {
      for {
        v1 <- a1
        v2 <- a2
      } yield (v1 ++ v2)
    }
    def mzero = Future.successful(Nil)
  }

假设我想编写一个泛型函数,该函数在类型容器上的泛型monoid上运行,例如在以下玩具示例中:

  // this compiles and works, but isn't good enough
  // for my more complicated example, which need to
  // specify that A is a container type
  def myAppend[A: Monoid](a1: A, a2: A): A = {
    implicitly[Monoid[A]].mappend(a1, a2)
  }

  // this is roughly what I want, but it doesn't compile
  def myAppend[A[_]: Monoid, B](a1: A[B], a2: A[B]): A[B] = {
    implicitly[Monoid[A[B]]].mappend(a1, a2)
  }

有没有办法让这项工作不使用隐式参数(我知道这种方法可行)。

编辑以包含指向更复杂示例的codereview.stackexchange的链接:https://codereview.stackexchange.com/questions/51571/custom-implementation-of-generic-future-sequence-in-scala

1 个答案:

答案 0 :(得分:0)

为了遇到此类问题的其他人的目的,自我回答链接到更复杂的上下文界限使用的材料。

您可以声明类型具有多个上下文边界:":" in type parameter

但是,如果类型本身采用多个参数,您似乎无法使用上下文绑定: http://www.scala-lang.org/old/node/5310.html

但是,通过使用具有更高kinded类型的类型别名,您可以创建类型接受类型参数的上下文边界,至少在某些情况下:Context bounds shortcut with higher kinded-types

如果我错了或过时,或者Scala更新了对此功能的更多支持,请更正我。