Scala - 使用参数指定函数中的类型

时间:2017-02-23 22:10:57

标签: scala

美好的一天,

我在大学有一项任务,我们需要为某种语言编写解析器。这种语言的核心功能之一是为NumC和StringC编写一个equals方法(核心语言中的数字和字符串表示)。这两种方法都将评估为BoolV(x),其中x为true或false(BoolV代表该语言中的布尔值)。

我使用以下代码成功完成了这项操作(请注意,所有输入都是ExprC,它是所有Core功能表示的超类。此外,public static IImmutableList<SupportRequest> GetSupportRequestsByClientId(this IDbSet<SupportRequest> dbSet, Guid clientId) { // Do stuff here return ...; } 函数负责将ExprC转换为值):

interp

您可能会注意到,这些功能非常相似;只检查的类型发生了变化(以及异常,但这些都是来自同一异常的子类)。

现在我想知道是否有一些实用程序会产生类似以下功能:

def str_cmp(l: ExprC, r: ExprC): BoolV = (interp(l), interp(r)) match {
  case (StringV(x), StringV(y)) => BoolV(x == y)
  case _ => throw NotStringException("Atleast one argument value does not evaluate to a String.")
}

def num_cmp(l: ExprC, r: ExprC): BoolV = (interp(l), interp(r)) match {
  case (NumV(x), NumV(y)) => BoolV(x == y)
  case _ => throw NotNumberException("Atleast one argument value does not evaluate to a number.")
}

这意味着可以以一种方式指定另一种def compare[A](l: ExprC, r: ExprC): BoolV = (interp(l), interp(r)) match { case (A(x), A(y)) => BoolV(x == y) case _ => throw NotValidArgument("Atleast one argument value does not evaluate to " + A + ".") l的interp必须导致的类型,以便比较方法进行评估而不是抛出错误。我知道上面的代码绝不是正确的语法,但我想知道是否有办法在Scala中编写这个功能。

1 个答案:

答案 0 :(得分:1)

使用ClassTag可能就是您正在寻找的解决问题的方法:

import reflect.ClassTag

def compare[T : ClassTag](l: ExprC, r: ExprC): BoolV = {
    val ct = implicitly[ClassTag[T]]
    (interp(l), interp(r)) match {
      case (ct(x), ct(y)) => BoolV(x == y)
      case _ => throw new Exception("At least one argument value does not evaluate to " + ct + ".")
    }
}
相关问题