Jos*_*cus 4 reflection scala case-class shapeless
是否可以一般性地替换案例类中的参数?更具体地说,我想要一个替代函数,它接收一个"查找"案例类和一个"替换"案例类(如语法规则的左侧和右侧)以及一个目标案例类,该函数将返回一个将case case类的参数替换为replace case类的新case类?该函数还可以简单地将case类(Product?)和一个函数应用于case类的所有参数/产品.
显然,给定一个特定的case类,我可以使用unapply和apply - 但是一般来说(给定任何case类)编写这种函数的最好/最简单/等方法是什么?
我想知道是否有一个很好的解决方案,使用Scala 2.10反射功能或无形的Iso.hlist.
例如,我真正希望能够做的是,给出如下的类......
class Op[T]
case class From(x:Op[Int]) extends Op[Int]
case class To(x:Op[Int]) extends Op[Int]
case class Target(a:Op[Int], b:Op[Int]) extends ...
// and lots of other similar case classes
Run Code Online (Sandbox Code Playgroud)
...有一个函数可以接受任意的case类并返回它的副本,其中任何类型的元素都替换为To类型的实例.
小智 5
如果你原谅插件,我想你会发现我们的Kiama语言处理库的重写组件非常适合这种用途.它提供了一种非常强大的战略规划形式.
这是一个完整的解决方案,To可以From在由case类实例构成的树中重写s .
import org.kiama.rewriting.Rewriter
class Op[T]
case class Leaf (i : Int) extends Op[Int]
case class From (x : Op[Int]) extends Op[Int]
case class To (x : Op[Int]) extends Op[Int]
case class Target1 (a : Op[Int], b : Op[Int]) extends Op[Int]
case class Target2 (c : Op[Int]) extends Op[Int]
object Main extends Rewriter {
def main (args : Array[String]) {
val replaceFromsWithTos =
everywhere {
rule {
case From (x) => To (x)
}
}
val t1 = Target1 (From (Leaf (1)), To (Leaf (2)))
val t2 = Target2 (Target1 (From (Leaf (3)), Target2 (From (Leaf (4)))))
println (rewrite (replaceFromsWithTos) (t1))
println (rewrite (replaceFromsWithTos) (t2))
}
}
Run Code Online (Sandbox Code Playgroud)
输出是
Target1(To(Leaf(1)),To(Leaf(2)))
Target2(Target1(To(Leaf(3)),Target2(To(Leaf(4)))))
Run Code Online (Sandbox Code Playgroud)
该replaceFromsWithTos值的概念是该rule构造提升了部分函数以能够对任何类型的值进行操作.在这种情况下,部分函数仅在From节点处定义,用节点替换它们To.该everywhere组合子说:"我的应用参数树中的所有节点,不改变的地方的说法不适用.
除了这种简单的重写之外,还可以做得更多.有关血淋淋的细节,请参阅主要的Kiama重写文档,包括更多示例的链接.