[英]In Scala, how can I define a companion object for a class defined in Java?
[英]How can I define an HKT for instance (over object) methods in Scala?
如何在Scala中定义HKT以提供方法(如map
)作为实例上的方法而不是对象上的函数?
我知道你可以
trait M[F[_]] {
def map[A, B](f: F[A])(fn: A => B): F[B]
}
object Q extends M[Q] {
def map[A, B](f: Q[A])(fn: A => B) = new Q(fn(f.e))
}
class Q[A](val e: A)
Q.map(new Q(1))(_.toDouble)
但是,我想在实例上使用map
。 我没有看到任何文献这样做,所以我写了以下内容。
trait M[A, F[A]] {
def map[B](f: A => B): F[B]
}
class Q[A](val e: A) extends M[A, Q] {
def map[B](f: A => B) = new Q(f(e))
}
new Q(1).map(_.toDouble)
它是惯用的Scala吗? map
应该做什么? 与上面的对象版本相比有限制吗? (另外, extends M[A, Q[A]]
它不会编译 - 为什么?)
我见过
trait M[A] {
def map[B](f: A => B): M[B]
}
但是Q
的map
可以返回一个class R[A] extends M[A]
,这是不希望的。
有一个专门用于此的库: https : //github.com/mpilquist/simulacrum
你也可以自己做。 典型的模式是定义一个对应的隐式MOps
类或其他:
trait M[F[_]] {
def map[A, B](f: F[A])(fn: A => B): F[B]
}
implicit class MOps[F[_] : M, A](x: F[A]) {
def map[B](f: A => B): F[B] = implicitly[M[F]].map(x)(f)
}
然后示例用法:
case class Box[A](a: A)
implicit val BoxM = new M[Box] {
def map[A, B](f: Box[A])(fn: A => B): Box[B] = Box(fn(f.a))
}
Box(2).map(_.toString)
但它是很多样板,所以simulacrum为你做的一切(以及更多)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.