2010-02-16 4 views
13

나는 기본적으로 그룹 형태의 배열이vararg 사례 클래스를 사용하여 패턴 일치를 수행하는 방법은 무엇입니까?

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

나는 그룹을 알고지도와 왼쪽으로 접을 필요가 있지만 실제로는 그럴 수 없다. 감사합니다.

답변

8

vararg 패턴 일치 구문은 다소 strange입니다. 마지막 줄에, 당신은 주름의 /: 표기법을 사용하여 0으로 시작하는 모든 하위 shapes의 크기를 정리해 것을

def size(s: Shape) : Int = s match{ 
    case Rectangle(x,y) => 1 
    case Circle(r) => 1 
    case Location(x,y,shape) => 1 
    case Group(shapes @ _*) => (0 /: shapes) { _ + size(_) } 
} 

참고.


작동 방식 : 접기는 주어진 기능을 사용하여 시퀀스의 요소를 누적합니다.

그래서리스트의 합을 계산하기 위해, 우리는 작성합니다 (하스켈 스타일) 0부터 시작 주어진 추가 기능 목록의 모든 요소를 ​​결합 할

fold (\total element -> total + element) 0 list 

(따라서 계산 합계).

스칼라에서

, 우리는이 방법을 쓸 수 있습니다 : 두 번째는 아마도 바람직하고,

(0 /: list) { (total, element) => total + element } 

(0 /: list) { _ + _ } 
+0

이것은 중복을 설명하지 않습니다. 그게 중요합니까? – PanCrit

+0

마지막 라인이 너무 이상하게 작동하는 방법을 설명해 주시겠습니까? 사례 그룹 (shapes @ _ *) => (0/: 도형) {_ + size (_)} – tom

+0

@PanCrit : 스칼라에는 유창하지 않습니다. * 중복되는 부분에 대해 설명해 주시겠습니까? ? – Dario

17

이 중 하나가 작동을 단순화 할 수있다 처음에는 조금 이상한 경우 섬광. Scala Reference에서 8.1.9 패턴 시퀀스를 참조하십시오.

case g: Group => g.shape.map(size(_)).sum 

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

이것은 스칼라 2.8을 사용하고 있습니다. sum은 이전 버전에서는 작동하지 않을 수 있습니다.

+0

겹침을 고려하지 않았습니다. 그게 중요한가요? – PanCrit

+5

제 생각에 그 질문은 기하학보다는 스칼라에서 패턴 매칭에 관한 것입니다. – retronym

2

첫 번째 단계는 사용자가 의미하는 바를 파악하는 것입니다. 두 가지 가장 확실한 선택은 모든 도형이 포함하는 전체 영역과 그 중 모든 사각형을 포함하는 최소 사각형입니다. 서클의 경우 실제 지역을 반환하면 실제 지역으로 가야합니다.

답할 방법이 없습니다. 나는 최소한의 둘러싸는 직사각형에 무작위로 1000 개의 무작위 다트를 던지면서 점을 치는 다트의 비율로 그 지역을 계산하는 것을 고려해 볼 수 있습니다. 견적이 수용 가능한 응답입니까?

모든 모양이 원과 직사각형으로 보장됩니까? 그 (것)들을 위해 작동 할 해결책을 함께 자갈을 수 있습니다. Shapes가 더 이상 확장 될 수 있다면 작동하지 않습니다.

0

케이스 g :. 그룹 => g.shape.map (크기 (_))는

경우 그룹 => ss.map (* @ SS)를 합산 (크기 ()).

이들 모두 합

오류 값 (SUM) 서열의 구성원이 제공 [지능]
그러나이 오엔이
경우 그룹 작업 (형상 @ _ *) => (0/: 도형) {_ + 사이즈 (_)

+2

답변을 질문으로 게시하지 말고 질문을 편집하십시오! – Dario

1

위치와 크기는 형상이 높은 카운트를

경우 위치 (X, Y, 모양) => 크기 (형상)

인해 그룹 일 수 있기 때문에 크기를 얻기 위하여 드릴 다운한다고 size가 Shape의 형상의 수의 경우는