我一直在阅读与新反射api一起出现的新TypeTag.似乎Manifest应该被这个新概念所取代.任何人都可以发布一些代码示例来展示好处吗?
一些参考:
我有一个函数,它能够知道一个对象是否是一个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嵌入式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) 我试图发现特征的值是否有与之关联的注释.回顾斯卡拉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注释?
我正在开发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.
我正在为一些SBT项目生成ScalaDoc HTML文件(在多项目配置中).如果我在SBT控制台中执行doc,则可以很好地生成文档,但它会部署在每个项目的独立目录中.由于所有项目彼此非常相关(就包名而言),我想生成一个唯一的ScalaDoc目录作为输出.值得一提的是,由于某些涉及的宏所需的双重编译过程,我无法将所有源集中在一起.有没有办法解决这个问题?
我有点被以下(宏注释)情况阻止.假设我有一个被调用的注释@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
, …
我试图在Eclipse 3.7.2中编译一个(Scala)宏,Scala IDE插件可用于Scala 2.10.0-M3,但我遇到以下错误:
"没有找到宏实现:XXXXX(最常见的原因是你不能在定义它们的同一个编译运行中使用宏实现)如果你确实需要定义宏实现和你的程序的其余部分,考虑两阶段在第二阶段使用-Xmacro-fallback-classpath进行编译,指向第一阶段的输出"
我已经知道如何使用简单的编辑器和终端来避免它(只是跟着错误信息),但是有可能在Eclipse中实现双阶段任务吗?
我试图用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生成源代码的其他项目?
我在围绕state
monad做一些 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 …
scala ×7
scala-2.10 ×7
macros ×4
annotations ×2
reflection ×2
sbt ×2
coq ×1
instanceof ×1
let ×1
scala-ide ×1
scaladoc ×1
type-erasure ×1