2012-10-03 32 views
8

Tôi có một lớp trường hợp như sau:Scala vịt gõ mô hình kết hợp

// parent class 
sealed abstract class Exp() 

// the case classes I want to match have compatible constructors 
case class A (a : Exp, b : Exp) extends Exp 
case class B (a : Exp, b : Exp) extends Exp 
case class C (a : Exp, b : Exp) extends Exp 

// there are other case classes extending Exp that have incompatible constructor, e.g. 
//  case class D (a : Exp) extends Exp 
//  case class E() extends Exp 
// I don't want to match them 

Tôi muốn để phù hợp với:

var n : Exp = ... 
n match { 
    ... 
    case e @ A (a, b) => 
     foo(e, a) 
     foo(e, b) 
    case e @ B (a, b) => 
     foo(e, a) 
     foo(e, b) 
    case e @ C (a, b) => 
     foo(e, a) 
     foo(e, b) 
    ... 
} 

def foo(e : Exp, abc : Exp) { ... } 

là Có cách nào để hợp nhất mà ba trường hợp vào một trường hợp duy nhất (mà không cần thêm một lớp cha mẹ trung gian vào A, B, C)? Tôi không thể thay đổi định nghĩa A, B, C hoặc Exp. Một số loại:

var n : Exp = ... 
n match { 
    ... 
    case e @ (A | B | C) (a, b) => // invalid syntax 
     foo(e, a) 
     foo(e, b) 
    ... 
} 

mà rõ ràng là không làm việc, và không phải làm:

var n : Exp = ... 
n match { 
    ... 
    case e @ (A (a, b) | B (a, b) | C (a, b)) => // type error 
     foo(e, a) 
     foo(e, b) 
    ... 
} 

Trả lời

11

Trong khi sau "giải pháp" thực sự chỉ là một cách khác nhau của văn bản những gì bạn đã có, nó có thể giúp nếu bạn cần sử dụng cùng một số match ở nhiều nơi và muốn tránh trùng lặp mã.

Sau đây tùy chỉnh unapply:

object ExpABC { 
    def unapply(e:Exp):Option[(Int, Int)] = e match { 
     case A(a, b) => Some(a, b) 
     case B(a, b) => Some(a, b) 
     case C(a, b) => Some(a, b) 
     case _ => None 
    } 
} 

cho phép bạn viết

n match { 
    case e @ ExpABC(a, b) => 
     println(e) 
     println(a) 
     println(b) 
} 

Bằng cách này bạn không cần phải sửa đổi các lớp học ban đầu ở tất cả. Tôi không biết cách nào tốt hơn để làm điều này không liên quan đến việc sửa đổi các lớp học A/B/C, nhưng tôi mong muốn tìm hiểu @ Stackoverflow;)

Các vấn đề liên quan