参数类的Clojure模式匹配

时间:2014-10-15 18:05:02

标签: scala clojure pattern-matching

我有一个用Scala编写的简单程序,它将逻辑表达式作为case类的成员来操作,它们扩展了Expr trait(下面的代码)。然后我有一些函数只是在参数的类上进行模式匹配并执行一些操作。

sealed trait Expr 

case class Implication(lhs: Expr, rhs: Expr) extends Expr {
  override def toString = "(" + lhs.toString + "->" + rhs.toString + ")"
}

case class Negation(body: Expr) extends Expr {
  override def toString = "!" + body.toString
}

case class Conj(lhs: Expr, rhs: Expr) extends Expr {
  override def toString = "(" + lhs.toString + "&" + rhs.toString + ")"
}

case class Disj(lhs: Expr, rhs: Expr) extends Expr {
  override def toString = "(" + lhs.toString + "|" + rhs.toString + ")"
}

case class Variable(name: String) extends Expr {
  override def toString = name
}

功能示例:

def substitute(map: m.HashMap[String, Expr]): Expr = this match {
    case Variable(name) => map.getOrElse(name, this)
    case Conj(a, b) => Conj(a.substitute(map), b.substitute(map))
    case Disj(a, b) => Disj(a.substitute(map), b.substitute(map))
    case Implication(a, b) => Implication(a.substitute(map), b.substitute(map))
    case Negation(a) => Negation(a.substitute(map))
}

问题是:我如何在Clojure中模仿相同的功能?基本上我只想区分函数参数的类和模式匹配,最好用守卫。

2 个答案:

答案 0 :(得分:0)

表达式的核心看起来是带有标记节点的递归数据结构。您可以在Clojure中使用Red-Black tree的示例构建表达式数据结构。

关键的见解是表达式树用嵌套的普通Clojure数据类型表示。在红黑示例中,每个节点是一个4元组[类型左子值右子]。在您的示例中,将表达式表示为[type& amp;孩子。

在任何一种情况下,core.match都使用模式匹配来处理简单的Clojure类型,如矢量和关键字。您可以将表达式匹配为1对1。

答案 1 :(得分:0)

可以使用ifcondcondp或其他条件运算符来解决问题。要查找班级,请使用classtype个函数。

使用拉链来行走和编辑地图树。 http://ravi.pckl.me/short/functional-xml-editing-using-zippers-in-clojure/

有很多方法可以在地图中标记条目:

  • {:tag:Variable:value 42}
  • (defrecord Variable [value])

看看活跃的灵感 - https://github.com/cgrand/enlive