斯卡拉的象征性差异

时间:2012-03-02 19:43:33

标签: scala math sicp symbolic-math

我想在Scala中使用像SICP中所做的模式匹配来创建符号微分函数。我希望能够写出这样的东西:

differentiate(exp) = exp match
{
  case + => 
  case * =>
}

Scala中是否可以使用“原生”表达式?

3 个答案:

答案 0 :(得分:2)

你尝试过吗? :)

sealed trait Exp
case object + extends Exp
case object * extends Exp

def differentiate(exp: Exp) = exp match {
  case + => println("plus")
  case * => println("times")
}

scala> differentiate(*)
times

但是

scala> differentiate(+)
<console>:1: error: illegal start of simple expression
       differentiate(+)
                  ^

嗯,我想这对所有符号都不起作用。

答案 1 :(得分:1)

关于“原生”表达,没有。并不是的。你可以使用符号:

def foo(x: Symbol) = x match {
  case '+ => "Plus"
  case '* => "Times"
}

如果您注意到,符号也是SICP解析事物的方式。见SICP 2.3.1

(deriv '(* x y) 'x)
y

它可能有更漂亮的符号匹配语法,但最后,这就是它所做的一切。

答案 2 :(得分:1)

我之前看过的每个例子都涉及表达式树。您可以使用案例类在Scala中轻松构建它。例如,涉及模式匹配和面向对象风格的粗略草图:

trait Exp {
  def differentiate: Exp
}
case class Const( value: Double ) extends Exp {
  def differentiate = Const(0)
}
case class Var( label: String, power: Double ) extends Exp {
  def differentiate = this match {
    case Var(l,0.0) => Const(0)
    case Var(l,p) => Mul( Const(p), Var(l,p-1) )
  }
}
case class Add( left: Exp, right: Exp ) extends Exp {
  def differentiate = Add( left.differentiate, right.differentiate )
}
case class Mult( left: Exp, right: Exp ) extends Exp {
  def differentiate = ( left, right ) match {
    case ( Const(c), exp ) => Mul( Const(c), exp.differentiate )
    case ( exp, Const(c) ) => Mul( Const(c), exp.differentiate )
    case (e1, e2) => Add( Mul( e1.differentiate, e2), Mul( e1, e2.differentiate ) )
  }
}