【问题标题】:How to test type equality at type-level in scala?如何在scala中的类型级别测试类型相等性?
【发布时间】:2013-11-12 16:25:16
【问题描述】:

我想做一些类型级别的编程。 Scala 类型的宏已经死了,看起来 shapeless 无法做我想做的事。 如果我能让下面的代码工作,我所有的问题都会得到解决 (此代码借自http://apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/http://michid.wordpress.com/2010/06/18/type-level-programming-equality/) 它显示了具有“类型删除”运算符的 HList 的实现。 该错误来自“EQ”结构,该结构测试两种类型是否等效以便删除。 在我的情况下,它似乎总是返回 false。我认为这是因为我使用了“别名”(?),但我不知道如何克服这个困难。

class Root {

  def typed[T](t: => T) {}
}

trait BooleanCompute extends Root {

  trait BOOL {
    type OUT <: BOOL

    type SELECT[TrueAction <: Action, FalseAction <: Action, Action] <: Action
  }

  case class TRUE() extends BOOL {
    type OUT = TRUE

    type SELECT[TrueAction <: Action, FalseAction <: Action, Action] = TrueAction
  }

  case class FALSE() extends BOOL {
    type OUT = FALSE

    type SELECT[TrueAction <: Action, FalseAction <: Action, Action] = FalseAction
  }

}
object  BooleanCompute extends BooleanCompute

import BooleanCompute._

case class Equality[A]() {
  def check(x: A)(implicit t: TRUE) = t

  def check[B](x: B)(implicit f: FALSE) = f
}

object Equality {
  def witness[T] = null.asInstanceOf[T]

  implicit val t: TRUE = null
  implicit val f: FALSE = null
}

trait EQ[A, B] extends {

  import Equality._

  type OUT = out.type
  val out = Equality[A]() check witness[B]


  val test1 = Equality[List[Boolean]] check witness[List[Boolean]]
  implicitly[test1.OUT =:= TRUE]
  // Does not compile since tt is True
  //implicitly[test1.t =:= FALSE]

  val test2 = Equality[Nothing] check witness[AnyRef]
  // Does not compile since ft is False
  // implicitly[test2.t =:= TRUE]
  implicitly[test2.OUT =:= FALSE]
}

object HList extends Root {

  type :+:[H, T <: HList] = HCons[H, T]
  val :+: = HCons

  sealed trait HList {
    self: HList =>

    type SELECT[ConsAction <: Action, NilAction <: Action, Action] <: Action

    type Remove[A] <: HList
  }

  final case class HCons[Head, Tail <: HList](head: Head, tail: Tail) extends HList {
    self: HList =>

    type SELECT[ConsAction <: Action, NilAction <: Action, Action] = ConsAction

    type Remove[A] = SELECT[
      EQ[Head, A]#OUT#SELECT[Tail#Remove[A], Head :+: Tail#Remove[A], HList],
      HNil,
      HList]

    def :+:[T](v: T) = HCons(v, this)
  }

  sealed case class HNil() extends HList {
    type SELECT[ConsAction <: Action, NilAction <: Action, Action] = NilAction

    type Remove[A] = HNil

    def :+:[T](v: T) = HCons(v, this)
  }

}

object yo extends App {

  import HList._

  case class AA()
  case class BB()
  case class CC()
  case class DD()

  type YO =  AA :+: BB :+:CC :+: HNil
  type YoRemoved =  AA :+:  CC :+: HNil
  val a = AA() :+: CC() :+: HNil()

  typed[YoRemoved](a)
  typed[YO#Remove[BB]](a)
}

【问题讨论】:

  • "Scala 宏已死" -- 说什么?
  • 他们怎么死了?
  • 对不起,type 宏已经死了,我很快就写信了。它已被编辑。

标签: scala shapeless type-level-computation


【解决方案1】:

你对 shapeless 有什么问题?以下效果很好,

scala> val yo = AA() :: BB() :: CC() :: HNil
yo: AA :: BB :: CC :: HNil = AA() :: BB() :: CC() :: HNil

scala> typed[YO](yo) // Compiles

scala> val yoRemoved = yo.filterNot[BB]
yoRemoved: AA :: CC :: HNil = AA() :: CC() :: HNil

scala> typed[YoRemoved](yoRemoved)  // Compiles

【讨论】:

猜你喜欢
  • 2013-07-19
  • 2019-10-09
  • 2012-07-12
  • 2011-01-15
  • 2013-10-03
  • 1970-01-01
  • 2012-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多