2015-05-29 9 views
2

у меня есть черта с типом члена, и хотят иметь макрос с подписью, содержащей этот тип:макросы Scala, относящиеся к типу члена

trait Foo { 
    class Bar[A] { ... } 

    def baz[A](x: Bar[A]): Bar[A] = macro bazImpl[A] 

    def bazImpl[A: c.WeakTypeTag](c: blackbox.Context)(x: c.Expr[Bar[A]]) = ... 
} 

Это не работает, так как bazImpl должны принадлежать либо статический (то есть нечлен) object или к пакету макросов. Но ни в одном случае у меня нет foo: Foo, поэтому я мог написать foo.Bar[A].

Один из способов я могу думать о том, чтобы использовать Foo#Bar[A] и добавить слепки:

trait Foo { 
    class Bar[A] { ... } 

    def baz[A](x: Bar[A]): Bar[A] = Foo.baz1(x).asInstanceOf[Bar[A]] 

    def bazImpl[A: c.WeakTypeTag](c: blackbox.Context)(x: c.Expr[Bar[A]]) = ... 
} 

object Foo { 
    def baz1[A](x: Foo#Bar[A]): Foo#Bar[A] = macro bazImpl[A] 

    def bazImpl[A: c.WeakTypeTag](c: blackbox.Context)(x: c.Expr[Foo#Bar[A]]): c.Expr[Foo#Bar[A]] = ... 
} 

Но я хотел бы избежать этого (и потому, что это не совсем типобезопасным и потому, что реальный случай является более сложным,). Любые альтернативы?

+0

Можете ли вы создать вложенный объект-компаньон вместе с вложенным классом? Другими словами, создайте объект 'Bar', вложенный в функцию' Foo', которая содержит метод 'bazImpl'? –

+0

@BenReich Как сказано, реализация макроса должна быть в объекте _static_. Объект, вложенный в 'Foo', не является статическим (как я понимаю, по крайней мере). –

ответ

2

Если вы используете Scala 2.11, просто напишите c.Tree везде, а не c.Expr. Это приведет к сокращению шаблона с указанием тех же типов в макросчетах, что и в макрообменах, при практически нулевой стоимости. Единственным потенциальным недостатком деревьев по сравнению с exprs является reify, что требует, чтобы splicees были exprs, но поскольку большинство метапрограмм в Scala написаны с квазикварталами в эти дни, скорее всего, это не будет иметь для вас никакого значения.

+0

Можете ли вы объяснить больше о различии между Tree и Expr и о том, как Tree допускает правильный вложенный класс, но Expr не делает этого? –

+1

@EugeneBurmako Это, возможно, стоит упомянуть в обзоре макросов (если это не так, я не видел его, по крайней мере). –

+0

Как это ответ на исходный вопрос? –