Scala 如何使用vararg case类执行模式匹配?

Scala 如何使用vararg case类执行模式匹配?,scala,functional-programming,pattern-matching,Scala,Functional Programming,Pattern Matching,我有一组这样的案例类 abstract class Shape case class Rectangle(width: Int, height: Int) extends Shape case class Location(x: Int, y: Int, shape: Shape) extends Shape case class Circle(radius: Int) extends Shape case class Group(shape: Shape*) extends S

我有一组这样的案例类

abstract class Shape  
case class Rectangle(width: Int, height: Int) extends Shape  
case class Location(x: Int, y: Int, shape: Shape) extends Shape  
case class Circle(radius: Int) extends Shape  
case class Group(shape: Shape*) extends Shape
其中基本上是一组形状的数组。我需要定义一个计算尺寸的尺寸方法 对于矩形、圆形和位置,直接返回一个。但我在团队中遇到了困难

object size extends Shape{  
  def size(s: Any) : Int = s match {  
    case Rectangle(x,y) => 1  
    case Group  // how to do it? Also having case Group(shape : Shape*) gives an error  
    case Circle(r) => 1    
    case Location(x,y,shape) => 1   
  }  
}  
我知道对于小组我需要使用地图和左折,但我真的不能为它创建一个逻辑。
谢谢

vararg模式匹配的语法有些复杂

请注意,在最后一行中,您使用折叠的
/:
-符号将所有子
形状的大小相加,从零开始


工作原理:折叠使用给定函数累积序列元素

为了计算一个列表的和,我们要写(Haskell风格)

它将列表中的所有元素与给定的从0开始的加法函数相结合(从而计算总和)

在Scala中,我们可以这样编写:

(0 /: list) { (total, element) => total + element }
可以简化为

(0 /: list) { _ + _ }

这两种方法都可以,如果乍一看有点奇怪的话,第二种可能更可取。参见第8.1.9节中的模式序列


这是在使用Scala 2.8
sum
在旧版本上可能不起作用。

第一步是弄清楚你的意思。两个最明显的选择是所有形状所覆盖的总面积,以及包含所有形状的最小矩形。如果圆返回实际面积,则可能必须使用实际面积

没有封闭式的方法来回答这个问题。我可能会考虑在最小的封闭矩形上投掷一千个随机镖,并将该区域估计为命中占空点的镖的百分比。评估是可接受的回答吗


你保证所有的形状都是圆和矩形吗?你也许能够拼凑出一个对他们有用的解决方案。如果形状可以进一步扩展,那么这将不起作用。

案例g:Group=>g.shape.map(size()).sum

病例组(ss@*)=>ss.map(size()).sum

这两个参数都给出了错误值sum不是Seq[Int]的成员
但是,此oen有效

案例组(shapes@*)=>(0/:shapes){uuz+大小({/p>位置大小应向下钻取以获得大小,因为shapes可能是导致更高计数的组

箱子位置(x、y、形状)=>尺寸(形状)


也就是说,如果大小是形状中形状的数量,这并不说明重叠。这很重要吗?我的假设是,问题在于Scala中的模式匹配,而不是几何体。这不说明重叠。这有关系吗?你能解释一下最后一行是如何工作的吗?太奇怪了????案例组(shapes@*)=>(0/:shapes){uu+size()}@PanCrit:我对Scala不是很熟练-请你解释一下重叠的含义好吗?@tom
@
符号的意思是“将与我右边的图案匹配的任何东西分配给我左边的标识符”。例如,
r@Rectangle(x,y)
将整个
矩形
分配给
r
,并将其分解分配给
x
y
。现在,模式
.*
只意味着“任何数字”@Dario我想PanCrit是说,你不能只添加所有形状的大小,因为它们可能重叠。那么,联合的大小将小于所有大小的总和。请不要将问题作为答案发布,而是编辑你的问题!
(0 /: list) { (total, element) => total + element }
(0 /: list) { _ + _ }
case g: Group => g.shape.map(size(_)).sum

case Group(ss @ _*) => ss.map(size(_)).sum