Scala递归宏?
发布时间:2020-12-16 18:34:00 所属栏目:安全 来源:网络整理
导读:我想知道 Scala是否支持递归宏扩展,例如我是 trying to write a lens library与镜头宏,这样做: case class C(d: Int)case class B(c: C)case class A(b: B)val a = A(B(C(10))val aa = lens(a)(_.b.c.d)(_ + 12)assert(aa.b.c.d == 22) 鉴于镜头(a)(_.b.c.d
我想知道
Scala是否支持递归宏扩展,例如我是
trying to write a lens library与镜头宏,这样做:
case class C(d: Int) case class B(c: C) case class A(b: B) val a = A(B(C(10)) val aa = lens(a)(_.b.c.d)(_ + 12) assert(aa.b.c.d == 22) 鉴于镜头(a)(_.b.c.d)(f),我想将其转换为a.copy(b =镜头(a.b)(_.c.d)(f)) 编辑: 但是,我无法弄清楚从List [TermName]创建访问器的通用方法,例如对于上面的例子,假设我有List(TermName(‘b’),TermName(‘c’),TermName(‘d’))),我想生成一个匿名函数_.bcd ie(x:A) => x.b.c.d.我怎么做? 基本上,我怎样才能以通用方式编写these lines? 解决方法
实际上我设法让它工作:
https://github.com/pathikrit/sauron/blob/master/src/main/scala/com/github/pathikrit/sauron/package.scala
这是完整的来源: package com.github.pathikrit import scala.reflect.macros.blackbox package object sauron { def lens[A,B](obj: A)(path: A => B)(modifier: B => B): A = macro lensImpl[A,B] def lensImpl[A,B](c: blackbox.Context)(obj: c.Expr[A])(path: c.Expr[A => B])(modifier: c.Expr[B => B]): c.Tree = { import c.universe._ def split(accessor: c.Tree): List[c.TermName] = accessor match { // (_.p.q.r) -> List(p,q,r) case q"$pq.$r" => split(pq) :+ r case _: Ident => Nil case _ => c.abort(c.enclosingPosition,s"Unsupported path element: $accessor") } def join(pathTerms: List[TermName]): c.Tree = (q"(x => x)" /: pathTerms) { // List(p,r) -> (_.p.q.r) case (q"($arg) => $pq",r) => q"($arg) => $pq.$r" } path.tree match { case q"($_) => $accessor" => split(accessor) match { case p :: ps => q"$obj.copy($p = lens($obj.$p)(${join(ps)})($modifier))" // lens(a)(_.b.c)(f) = a.copy(b = lens(a.b)(_.c)(f)) case Nil => q"$modifier($obj)" // lens(x)(_)(f) = f(x) } case _ => c.abort(c.enclosingPosition,s"Path must have shape: _.a.b.c.(...),got: ${path.tree}") } } } 并且,是的,Scala确实递归地应用了相同的宏. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- kmp算法--求字符串子串--《数据结构》严蔚敏
- scala – Actor和Future:引用onComplete中的actor消息
- bootstrap表单学习笔记3-2
- Typescript / Angular2 http.post不设置标题
- 在docker容器中使用akka应用程序的问题
- twitter-bootstrap – Twitter Bootstrap Carousel – 不要
- Angular 4“无法绑定到’ngModel’,因为它不是’input’的已
- WebService
- google-app-engine-如何使用Dockerfile运行Google App Engi
- Angular 4 依赖注入教程之七 ValueProvider的使用