简体   繁体   English

案例类和特征

[英]case class and traits

I want create a special calculator. 我想创建一个特殊的计算器。 I think that case class is a good idea for operations: 我认为case class对于操作来说是一个好主意:

sealed class Expr
case class add(op1:Int, op2:Int) extends Expr
case class sub(op1:Int, op2:Int) extends Expr
case class mul(op1:Int, op2:Int) extends Expr
case class div(op1:Int, op2:Int) extends Expr
case class sqrt(op:Int) extends Expr
case class neg(op:Int) extends Expr
/* ... */

Now I can use match-case for parsing input. 现在我可以使用match-case来解析输入。 Maybe, I should also use traits (ie: trait Distributivity , trait Commutativity and so on), Is that posible? 也许,我也应该使用traits (即: trait Distributivitytrait Commutativity等),这是可能的吗? Is that a good idea? 这是一个好主意吗?

Before you start adding traits of not-so-clear additional value, you should get the basics right. 在开始添加不那么明确的附加值的特征之前,您应该掌握正确的基础知识。 The way you do it now makes these classes not very useful, at least not when building a classical AST (or "parse tree"). 你现在这样做的方式使这些类不是很有用,至少在构建经典AST(或“解析树”)时不是这样。 Imagine 4 * (3+5). 想象一下4 *(3 + 5)。 Before you can use the multiplication operation, you have to evaluate the addition first. 在使用乘法运算之前,必须先评估加法。 That makes things complicated. 这让事情变得复杂。 What you usually want to have is the ability to write your formula "at once", eg Mul(4,Add(3, 5)). 你通常想要的是能够“立刻”编写你的公式,例如Mul(4,Add(3,5))。 However that won't work that way, as you can't get Ints or Doubles into your own class hierarchy. 但是这不会那样,因为你不能将Ints或Doubles放入你自己的类层次结构中。 The usual solution is a wrapper class for Numbers, say "Num". 通常的解决方案是Numbers的包装类,比如说“Num”。 Then we have: Mul(Num(4),Add(Num(3), Num(5)). This might look complicated, but now you have "all at once" and you can do things like introducing constants and variables, simplification (eg Mul(Num(1),x) --> x), derivation... 然后我们有:Mul(Num(4),Add(Num(3),Num(5))。这可能看起来很复杂,但现在你有“一下子”,你可以做一些事情,比如引入常量和变量,简化(例如Mul(Num(1),x) - > x),派生......

To get this, you need something along the lines 要做到这一点,你需要一些东西

sealed trait Expr {
  def eval:Int      
}
case class Num(n:Int) extends Expr {
  def eval = n
}
case class Neg(e: Expr) extends Expr {
  def eval = - e.eval() 
}
case class Add(e1: Expr, e2: Expr) extends Expr {
  def eval = e1.eval + e2.eval  
}
...

Now you can write a parser that turns "4*(3+5)" into Mul(Num(4),Add(Num(3), Num(5)), and get the result by calling eval on that expression. 现在你可以编写一个解析器,将“4 *(3 + 5)”变成Mul(Num(4),Add(Num(3),Num(5)),并通过在该表达式上调用eval来获得结果。

Scala contains already a parse library called parser combinators. Scala包含一个名为parser combinators的解析库。 For an example close to the code above see http://jim-mcbeath.blogspot.com/2008/09/scala-parser-combinators.html 有关上述代码的示例,请参阅http://jim-mcbeath.blogspot.com/2008/09/scala-parser-combinators.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM