小编jes*_*slg的帖子

新的Scala TypeTag如何改进(不推荐使用)Manifest?

可能重复:
Scala 2.10:什么是TypeTag以及如何使用它?

我一直在阅读与新反射api一起出现的新TypeTag.似乎Manifest应该被这个新概念所取代.任何人都可以发布一些代码示例来展示好处吗?

一些参考:

scala type-erasure scala-2.10

28
推荐指数
1
解决办法
3687
查看次数

如何知道对象是否是TypeTag类型的实例?

我有一个函数,它能够知道一个对象是否是一个Manifest类型的实例.我想将它迁移到一个TypeTag版本.旧功能如下:

def myIsInstanceOf[T: Manifest](that: Any) = 
  implicitly[Manifest[T]].erasure.isInstance(that)
Run Code Online (Sandbox Code Playgroud)

我一直在试验TypeTags,现在我有了这个TypeTag版本:

// Involved definitions
def myInstanceToTpe[T: TypeTag](x: T) = typeOf[T]
def myIsInstanceOf[T: TypeTag, U: TypeTag](tag: TypeTag[T], that: U) = 
  myInstanceToTpe(that) stat_<:< tag.tpe

// Some invocation examples
class A
class B extends A
class C

myIsInstanceOf(typeTag[A], new A)        /* true */
myIsInstanceOf(typeTag[A], new B)        /* true */
myIsInstanceOf(typeTag[A], new C)        /* false */
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来完成这项任务?参数化是否U可以省略,使用Any替代(就像在旧函数中一样)?

scala instanceof scala-2.10

19
推荐指数
2
解决办法
7504
查看次数

如何在宏中重用定义(AST)子树?

我正在使用Scala嵌入式DSL,宏正在成为实现我的目的的主要工具.我在尝试将传入宏表达式中的子树重用到结果宏中时遇到错误.情况非常复杂,但(我希望)我已将其简化为理解.

假设我们有这个代码:

val y = transform {
  val x = 3
  x
}
println(y) // prints 3
Run Code Online (Sandbox Code Playgroud)

其中'transform'是涉及的宏.虽然看起来它什么都没有,但它确实将显示的块转换为这个表达式:

3 match { case x => x }
Run Code Online (Sandbox Code Playgroud)

这是通过这个宏实现来完成的:

def transform(c: Context)(block: c.Expr[Int]): c.Expr[Int] = {
  import c.universe._
  import definitions._

  block.tree match {
    /* {
     *   val xNam = xVal
     *   xExp
     * }
     */
    case Block(List(ValDef(_, xNam, _, xVal)), xExp) =>
      println("# " + showRaw(xExp)) // prints Ident(newTermName("x"))
      c.Expr(
        Match(
          xVal, 
          List(CaseDef(
            Bind(xNam, Ident(newTermName("_"))),
            EmptyTree,
            /* xExp */ Ident(newTermName("x")) ))))
    case …
Run Code Online (Sandbox Code Playgroud)

macros scala abstract-syntax-tree scala-2.10

11
推荐指数
1
解决办法
1406
查看次数

如何在Scala 2.10中反映注释?

我试图发现特征的值是否有与之关联的注释.回顾斯卡拉2.10-M7反射API后,我认为getAnnotations方法(位于符号)可能是一个伟大的候选人,但它返回一个空的列表,如下面的REPL会话:

scala> class W extends scala.annotation.Annotation
defined class W

scala> trait A { @W val a: Int }
defined trait A

scala> typeOf[A].members.last
res0: $r.intp.global.Symbol = value a

scala> res0.getAnnotations
res1: List[$r.intp.global.AnnotationInfo] = List()
Run Code Online (Sandbox Code Playgroud)

这些"注释"是否与我试图处理的注释相同?我怎么知道a是否用W注释?

reflection annotations scala scala-2.10

9
推荐指数
1
解决办法
1363
查看次数

可以避免这种自由变量误差(在宏观扩张时产生)吗?

我正在开发DSL,并且在扩展宏时我遇到了"免费术语"失败.我想知道是否可以避免.我已将问题简化为以下情况.

假设我们有这个表达式:

val list = join {
  0
  1
  2
  3
}
println(list)
Run Code Online (Sandbox Code Playgroud)

其中join是一个宏,其实现是:

def join(c: Ctx)(a: c.Expr[Int]): c.Expr[List[Int]] = {
  import c.mirror._
  a.tree match {
    case Block(list, ret) =>
      // c.reify(List(new c.Expr(list(0)).eval, 
      //              new c.Expr(list(1)).eval,
      //              new c.Expr(list(2)).eval) :+ new c.Expr(ret).eval)
      c.reify((for (expr <- list) yield new c.Expr(expr).eval) :+ new c.Expr(ret).eval)
  }
}
Run Code Online (Sandbox Code Playgroud)

宏的目的是连接参数块中的所有元素并将它们返回到单个列表中.由于块的内容可以是变量,我不能使用注释的reify(这很好用).未注释的 - 用于理解,生成免费术语 - 抛出消息:

"宏扩展包含由Macros.scala中的连接定义的自由项变量列表:48:18.在将此变量拼接成reifee时,您是否忘记使用eval?如果您有跟踪自由项变量的麻烦,请考虑使用-Xlog-free-术语"

有没有办法在不出现此错误的情况下引入for-comprehension(或迭代器或其他)?顺便说一下,我使用的是2.10-M3.

macros scala-2.10

8
推荐指数
1
解决办法
1345
查看次数

如何合并SBT多项目的文档?

我正在为一些SBT项目生成ScalaDoc HTML文件(在多项目配置中).如果我在SBT控制台中执行doc,则可以很好地生成文档,但它会部署在每个项目的独立目录中.由于所有项目彼此非常相关(就包名而言),我想生成一个唯一的ScalaDoc目录作为输出.值得一提的是,由于某些涉及的宏所需的双重编译过程,我无法将所有源集中在一起.有没有办法解决这个问题?

scala sbt scaladoc

8
推荐指数
1
解决办法
900
查看次数

处理宏注释时无法访问Parent的成员

我有点被以下(宏注释)情况阻止.假设我有一个被调用的注释@factory,它旨在为apply相应的伴随对象中的带注释的特征生成一个方法.例如,鉴于trait A:

@factory
trait A {
  val a1: Int
}
Run Code Online (Sandbox Code Playgroud)

要生成的预期代码如下:

object A extends Factory[A] {
  def apply(_a1: Int) = new A {
    val a1 = _a1
  }
}
Run Code Online (Sandbox Code Playgroud)

现在假设我们有一个特征B,它继承自A:

@factory
trait B extends A {
  val b1: String
}
Run Code Online (Sandbox Code Playgroud)

这应该产生:

object B extends Factory[B] {
  def apply(_a1: Int, _b1: String) = new B {
    val a1 = _a1
    val b1 = _b1
  }
}
Run Code Online (Sandbox Code Playgroud)

在后一种情况下,我需要知道存在哪些属性A, …

macros code-generation annotations scala companion-object

8
推荐指数
1
解决办法
1250
查看次数

ScalaMacros和Eclipse

我试图在Eclipse 3.7.2中编译一个(Scala)宏,Scala IDE插件可用于Scala 2.10.0-M3,但我遇到以下错误:

"没有找到宏实现:XXXXX(最常见的原因是你不能在定义它们的同一个编译运行中使用宏实现)如果你确实需要定义宏实现和你的程序的其余部分,考虑两阶段在第二阶段使用-Xmacro-fallback-classpath进行编译,指向第一阶段的输出"

我已经知道如何使用简单的编辑器和终端来避免它(只是跟着错误信息),但是有可能在Eclipse中实现双阶段任务吗?

macros scala-ide scala-2.10

7
推荐指数
1
解决办法
2114
查看次数

是否可以使用SBT的反射?

我试图用SBT生成一些样板(对我来说这是一个全新的工具).我使用无形 sbt文件作为我的主要参考任务.我已经看到这个项目从头开始使用代码生成,但我的情况略有不同,因为我想从另一个类生成一些类.我假装使用新的Scala 2.10.0-M4反射功能.从SBT构建中获得反射需要什么基本配置?

到目前为止,sbt无法找到scala.reflect.runtime.universe包,我不知道问题是来自新的Scala jar分区还是来自错误的配置.此外,我的SBT 说:

[info] This is sbt 0.13.0-20120530-052139
[info] The current project is {file:/home/jlg/sandbox/abc/}abc
[info] The current project is built against Scala 2.10.0-SNAPSHOT
[info] 
[info] sbt, sbt plugins, and build definitions are using Scala 2.9.2
Run Code Online (Sandbox Code Playgroud)

那么,是否有人知道使用SBT生成源代码的其他项目?

reflection scala sbt scala-2.10

7
推荐指数
1
解决办法
631
查看次数

处理当前目标中的 let-in 表达式

我在围绕statemonad做一些 coq 证明时卡住了。具体来说,我已经将情况简化为这个证明:

Definition my_call {A B C} (f : A -> B * C) (a : A) : B * C :=
  let (b, c) := f a in (b, c).

Lemma mycall_is_call : forall {A B C} (f : A -> B * C) (a : A), my_call f a = f a.
Proof.
  intros A B C f a.
  unfold my_call.
  (* stuck! *)
Abort.
Run Code Online (Sandbox Code Playgroud)

调用后的结果目标unfold(let (b, c) := f a in …

let coq

6
推荐指数
1
解决办法
1071
查看次数