簡體   English   中英

返回使用派生特征的特征

[英]Return a trait that uses a derived trait

我想創建一個知道如何返回HList以及派生的HList的類型類。 理想情況下,它將具有以下結構:

trait Axis[A, L1 <: HList] {
  type L2 <: Mapped[L1,Ordering]#Out
  def vectorize(a:A): L1
  def orderings: L2
}

並會像

implicit object Tup2DI extends Axis[(Double, Int), Double :: Int :: HNil] {
  val m = implicitly[Mapped[Double :: Int :: HNil, Ordering]]
  type L2 = m.Out
  def vectorize(a: (Doubble, Int)) = a._1 :: a._2 :: HNil
  def orderings = implicitly[Ordering[Double]] :: implicitly[Ordering[Int]] :: HNil
}

問題在於,盡管有足夠的信息來確定類型,但是scala並沒有調整類型,因此在編譯過程中也是如此,從而導致以下錯誤:

 found   : shapeless.::[Ordering[Double],shapeless.::[Ordering[Int],shapeless.HNil]]
 required: Tup2DI.L2
    (which expands to)  Tup2DI.m.Out
             def orderings:L2 = implicitly[Ordering[Double]] :: implicitly[Ordering[Int]] :: HNil

如何以一種可以正確編譯的方式表達我所關心的信息?

好吧,在與#scala上知識淵博的人們討論完之后,向我指出了以下解決方法:

trait Axis[A, L1 <: HList] {
  val L2: Mapped[L1,Ordering]
  def vectorize(a:A): L1
  def orderings: L2.Out
}
object Axis {
  def reifiedT[L1 <: HList](implicit M: Mapped[L1,Ordering]): Mapped[L1,Ordering] {
    type Out = M.Out
  } = M
}

implicit object Tup2DI extends Axis[(Double, Int), Double :: Int :: HNil] {
  val L2 = Axis.reifiedT[L]
  def vectorize(a: (Double, Int)) = a._1 :: a._2 :: HNil
  def orderings:L2.Out = implicitly[Ordering[Double]] :: implicitly[Ordering[Int]] :: HNil
}

顯然,您必須告訴scala明確設置reified類型的Out,這是Scalaz庫中使用的一種技術。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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