SICP で行われているようなパターン マッチングを使用して、Scala で記号微分関数を作成したいと考えています。私はこのようなものを書くことができるようにしたいと思います:
differentiate(exp) = exp match
{
case + =>
case * =>
}
「ネイティブ」式のScalaでこれは可能ですか?
SICP で行われているようなパターン マッチングを使用して、Scala で記号微分関数を作成したいと考えています。私はこのようなものを書くことができるようにしたいと思います:
differentiate(exp) = exp match
{
case + =>
case * =>
}
「ネイティブ」式のScalaでこれは可能ですか?
試してみましたか?:)
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(+)
^
うーん、すべてのシンボルで機能するとは限りません。
「ネイティブ」表現については、いいえ。あまり。記号を使用できます。
def foo(x: Symbol) = x match {
case '+ => "Plus"
case '* => "Times"
}
お気づきの方もいらっしゃると思いますが、シンボルはSICPが物事を解析する方法でもあります。SICP2.3.1を参照してください
(deriv '(* x y) 'x)
y
シンボルを照合するための構文がよりきれいな場合もありますが、最終的にはそれだけです。
これまでに見たすべての例には、式ツリーが含まれていました。ケースクラスを使用して、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 ) )
}
}