【问题标题】:Return a trait that uses a derived trait返回使用派生特征的特征
【发布时间】:2014-01-08 22:18:04
【问题描述】:

我想创建一个知道如何返回 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 shapeless


    【解决方案1】:

    好的,在#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 显式设置具体化的 Out 类型,这是 Scalaz 库中使用的一种技术。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多