【发布时间】:2014-11-09 22:48:43
【问题描述】:
我正在尝试为 Scala 中的现有类 Elem 提供扩展方法。但是,我还希望任何M[Elem] 都可以使用这些操作,只要M 的Scalaz Functor 在范围内。行为始终是使用map 将操作应用于函子。
import scalaz._
import Scalaz._
class Elem
implicit class Ops[F[_]: Functor, A <% Elem](self: F[A]) {
def foo = self.map(_ => "bar")
}
val elem = new Elem
// TODO (nice to have): can we avoid this "explicit implicit" conversion?
implicit def idOps[A <% Elem](self: A) = new Ops[Id, A](self)
elem.foo // bar
Option(elem).foo // Some(bar)
List(elem).foo // List(bar)
我想更进一步,让我的扩展方法可用于任意深度的函子,例如List[Option[Elem]] 和Option[Option[Option[Elem]]]。我能够为两个函子的组合编写一个隐式提供 Ops,但我无法将其推广到任意嵌套深度:
// TODO: can we improve this to provide arbitrarily deep functor composition?
implicit def compositeOps[F[_]: Functor, G[_]: Functor, A <% Elem](self: F[G[A]]) = {
implicit val FG = implicitly[Functor[F]].compose[G]
new Ops[({ type FG[X] = F[G[X]] })#FG, A](self)
}
List(Option(elem)).foo // List(Some(bar))
Option(List(Option(elem))).foo // doesn't compile
有什么办法可以做到吗?
【问题讨论】: