2015-09-04 21 views
1

我正在编写一个在Scala中使用提取器来简化解析的小解析例程。在我的研究中,我发现了连接模式匹配(Pattern matching with conjunctions (PatternA AND PatternB)),这非常有用。使用我已经能够表达提取如下(仅提纲)。斯卡拉连接模式匹配,允许一个可选的术语

case object & { 
    def unapply[T](t : T) = Some(t, t) 
    } 


case object ParamA { 
    def unapply(jsonStr: String) : Option[String] = { 
     // If param A found in json return a Some(...) else None 
    ??? 
    } 
    } 
    case object ParamB { 
    def unapply(jsonStr: String) : Option[String] = { 
     // If param B found in json return a Some(...) else None 
     ??? 
    } 
    } 
    case object ParamC { 
    def unapply(jsonStr: String) : Option[String] = { 
     // If param C found in json return a Some(...) else None 
     ??? 
    } 
    } 

这些让我匹配强制ParamA和ParamB模式如下。

val jsonStr = "..." // A Json string 
    jsonStr match { 
     case ParamA(a) & ParamB(b) => { 
     // Got a and b. Now do something with it 
     } 
     case _ => { 

     } 
    } 

但是,如果我想匹配强制性至尊和ParamB模式,也可选择一个ParamC模式,我将如何去表达,在一个单行?

val jsonStr = "..." // A Json string 
    jsonStr match { 
     case ParamA(a) & ParamB(b) & Optional(ParamC(c)) /* Is this possible? */ => { 
     // Got a and b and an optional c. Now do something with it 
     } 
     case _ => { 

     } 
    } 

回答

1

您可以将未应用返回的值包装在另一个Option中。

case object OptionalParamC { 
    def unapply(jsonStr: String) : Option[Option[String]] = { 
     // If param C found in json return a Some(Some(...)) else Some(None) 
    } 
    } 

这样,它总是但是C在OptionalParamC(c)匹配或者是Some(x)None

更通用的方法是定义提取变压器

case object ? { 

    type Extractor = {def unapply(t: String): Option[String]} 

    case class Inner[T <: Extractor](extractor: T){ 
     def unapply(t: String) = Some(extractor.unapply(t)) 
    } 

    def apply[T <: Extractor](extractor: T) = Inner(extractor) 

    } 

然后用它转化ParamC

val OptionalC = ?(ParamC)

最后使用这样的:

ParamA(a) & ParamB(b) & OptionalC(c)

采用c beeing Some(x)None

+0

感谢您的响应。我确实尝试了这种方法,但它有以下缺点。如果在不同的case子句中,如果我查找强制ParamC的组合并说可选的ParamA,则两者的提取器签名将分别更改为返回Option和Option [Option]。我希望有一种方法来表达可选性,而不需要提取器返回嵌套在选项中的选项。 – shizambles

+0

已编辑的回复解决了您提到的可组合性问题。我的猜测是尽可能接近它。 –

+0

这几乎解决了我的问题。谢谢! – shizambles