假设我想使用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
答案 0 :(得分:0)
为了遇到此类问题的其他人的目的,自我回答链接到更复杂的上下文界限使用的材料。
您可以声明类型具有多个上下文边界:":" in type parameter
但是,如果类型本身采用多个参数,您似乎无法使用上下文绑定: http://www.scala-lang.org/old/node/5310.html
但是,通过使用具有更高kinded类型的类型别名,您可以创建类型接受类型参数的上下文边界,至少在某些情况下:Context bounds shortcut with higher kinded-types
如果我错了或过时,或者Scala更新了对此功能的更多支持,请更正我。