I want to make a symbolic differentiation function in Scala using its pattern matching like done in SICP. I'd want to be able to write something like this:

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

Is this possible in Scala on 'native' expressions?

有帮助吗?

解决方案

Every examples I've seen before involve an expression tree. You can build it easily in Scala with case classes. For instance, a rough sketch involving pattern matching and object-oriented style:

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 ) )
  }
}

其他提示

Did you try it? :)

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

But

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

Hmm, I guess it doesn't work for all symbols.

On "native" expressions, no. Not really. You can use symbols:

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

If you notice, symbols are also the way that SICP parses things. See SICP 2.3.1

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

It might have prettier syntax for matching on symbols, but in the end, that's all that it's doing.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top