2012-10-03 14 views
8

मैं तरह के मामले वर्ग है निम्नलिखित:स्काला बतख टाइपिंग पैटर्न मिलान

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

मैं मिलान करना चाहते हैं:

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) { ... } 

वहाँ मर्ज करने के लिए एक तरीका है कि एक ही मामले में तीन मामलों (ए, बी, सी में एक मध्यवर्ती मूल वर्ग जोड़ने के बिना)? मैं ए, बी, सी, या एक्सप की परिभाषा नहीं बदल सकता। किसी प्रकार का:

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

जो स्पष्ट रूप से काम नहीं करता है, और न तो कार्य करें:

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

उत्तर

11

जबकि निम्न "समाधान" वास्तव में सिर्फ लेखन क्या आपके पास पहले से का एक अलग तरीका है, यह मदद कर सकता है यदि आपको एक ही स्थान पर एक ही match का उपयोग करने की आवश्यकता है और कोड डुप्लिकेशन से बचना चाहते हैं।

कस्टम 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 
    } 
} 

आप

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

लिखने के लिए इस तरह से आप सभी को मूल वर्गों को संशोधित करने की जरूरत नहीं है की अनुमति देता है। मुझे ऐसा करने के बेहतर तरीके से अवगत नहीं है जिसमें ए/बी/सी कक्षाओं को संशोधित करने में शामिल नहीं है, लेकिन मैं @ स्टैक ओवरफ्लो सीखने के लिए उत्सुक हूं;)

संबंधित मुद्दे