2012-03-02 3 views
2

Я хочу сделать символическую функцию дифференциации в Scala, используя ее сопоставление с образцом, как это сделано в SICP. Я бы хотел написать что-то вроде этого:символическая дифференциация в Scala

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

Возможно ли это в Scala в «родных» выражениях?

+1

Вы имеете в виду 'def differiate (exp: T) = ...'? Какой тип exp? Строка? Функция? Оба не подходят для «+» или «*». –

+0

Возможно, это было вдохновением для вашего вопроса, но если вы его уже не видели, см. Расширенный пример в главе «Соответствие шаблону программирования в Scala» (http://www.artima.com/pins1ed/case-classes- and-pattern-matching.html) –

+0

@userunknown Выражение – Frawr

ответ

1

В каждом примере, который я видел ранее, используется дерево выражений. Вы можете легко построить его в Scala с классами case. Например, приблизительный эскиз, включающий сопоставление образцов и объектно-ориентированный стиль:

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)) 
    } 
} 
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(+) 
       ^

Хм, я предполагаю, что это не работает для всех символов.

+0

Хотя вы можете назвать это с помощью 'diffiate ($ plus)'. –

+0

Проблема с '+' ошибкой? – soc

+0

@soc Я не знаю о '+' в частности, но, конечно, вы ожидаете, что некоторые символы (зарезервированные символы, такие как '{', ';' и т. Д.) Не будут работать. –

1

На «родные» выражения, нет. На самом деле, нет. Вы можете символы Использование:

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

Если вы заметили, символы также способ, которым SICP разбирает вещи. См SICP 2.3.1

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

Это может иметь покрасивее синтаксис для сопоставления на символах, но в конце концов, это все, что он делает.

Смежные вопросы