Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala:验证类参数在编译时不是trait的实例_Scala_Shapeless_Scala Macros_Scala Reflect - Fatal编程技术网

Scala:验证类参数在编译时不是trait的实例

Scala:验证类参数在编译时不是trait的实例,scala,shapeless,scala-macros,scala-reflect,Scala,Shapeless,Scala Macros,Scala Reflect,在编译时,我想验证一个类参数是否不是一个特定trait T的实例。我知道如何在运行时使用require或case match进行验证,但我想知道如何在编译时做到这一点,以防止用户提供某种类型的对象混合 我已经研究了scala宏/反射,但无法完全理解这一点 trait A trait B trait T abstract class C extends A with B case class P(c: C){ require(!c.isInstanceOf[T]) // how to do

在编译时,我想验证一个类参数是否不是一个特定trait T的实例。我知道如何在运行时使用
require
case match
进行验证,但我想知道如何在编译时做到这一点,以防止用户提供某种类型的对象混合

我已经研究了scala宏/反射,但无法完全理解这一点

trait A
trait B
trait T
abstract class C extends A with B

case class P(c: C){
  require(!c.isInstanceOf[T]) // how to do this at compile time ?
}

// usage as below
object c1 extends C
object c2 extends C
object c3 extends C
object c4 extends C with T

val l = List(c1, c2, c3, c4).map(k => P(k)) // should fail at compile time

使用
列表
无法执行此操作。
列表(c1、c2、c3、c4)
中的所有元素都将属于同一类型,即
C
,其中一个元素的类型为
C和T的信息将丢失

newc{}
newc with T{}
c1、c2、c3、c4
的运行时值,编译器在编译
列表(c1、c2、c3、c4)
时无权访问它们


您可以使用
HList
执行此操作。使用
shapeless.Thank,它似乎无法处理扩展抽象类的单例对象。编译顺利完成。对不起,一开始我应该把我的问题描述得更好。我相信这可能不适用于单例对象,因为对单例对象的惰性计算。有什么解决办法吗?@bawejakunal懒惰的计算怎么可能与编译时相关?什么的变通办法?更好地描述您尝试的内容和获得的内容(编译错误等)@bawejakunal我想我已经在回答中解释了
List
HList
。这不能与
列表
一起使用。你还有其他问题吗?谢谢,这很有效,不过我想知道,如果不使用这种投影仪,这是否可以工作。对于一个我正在努力添加插件的项目,该插件在短期内可能不可行。@bawejakunal是的,当然这可以在没有lambda:
def noElementIsSubtypeOfT[L]类型的投影仪的情况下编写
def noElementIsSubtypeOfT[L <: HList](l: L)(implicit liftAll: LiftAll[* <:!< T, L]) = null

noElementIsSubtypeOfT(c1 :: c2 :: c3 :: HNil) // compiles
// noElementIsSubtypeOfT(c1 :: c2 :: c3 :: c4 :: HNil) // doesn't compile
def noElementIsSubtypeOfT[L <: HList : LiftAll[* <:!< T, *]](l: L) = null
case class P[U <: C](c: U)(implicit ev: U <:!< T)

P(c1) // compiles
P(c2) // compiles
P(c3) // compiles
// P(c4) // doesn't compile
case class P[U <: C : * <:!< T](c: U)