簡體   English   中英

如何在Scala中定義HKT for instance(over object)方法?

[英]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]
}

但是Qmap可以返回一個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM