- List(1,2,3) match {
- case 1 :: _ => println("found a list that starts with a 1")
- case _ => println("boo")
- }
The rule is very simple. An extractor object that returns Option[Tuple2[_,_]] (or equivalently Option[(_,_)]) can be expressed in this form.
In other words:
object X {def unapply(in:String):Option[(String,String)] = ...}
can be used in a case statement like: case first X head => ...
or case "a" X head => ...
.Example to extract out the vowels from a string:
- scala> object X { def unapply(in:String):Option[(RichString,RichString)] = Some(in.partition( "aeiou" contains _ )) }
- defined module X
- scala> "hello world" match { case head X tail => println(head, tail) }
- (eoo,hll wrld)
- // This is equivalent but a different way of expressing it
- scala> "hello world" match { case X(head, tail) => println(head, tail) }
- (eoo,hll wrld)
Example for Matching the last element in a list. Thanks to 3-things-you-didnt-know-scala-pattern.html:
- scala> object ::> {def unapply[A] (l: List[A]) = Some( (l.init, l.last) )}
- defined module $colon$colon$greater
- scala> List(1, 2, 3) match {
- | case _ ::> last => println(last)
- | }
- 3
- scala> (1 to 9).toList match {
- | case List(1, 2, 3, 4, 5, 6, 7, 8) ::> 9 => "woah!"
- | }
- res12: java.lang.String = woah!
- scala> (1 to 9).toList match {
- | case List(1, 2, 3, 4, 5, 6, 7) ::> 8 ::> 9 => "w00t!"
- | }
- res13: java.lang.String = w00t!
Awesome, this definitely helps me to understand this type of pattern matching, thanks!
ReplyDeleteNote that my last-list-element extractor does not cover all cases- I've made it shorter for the purpose of the example. In order to be complete, you need to match empty lists:
ReplyDeleteobject ::> {def unapply[A] (l: List[A]) = l match {
case Nil => None
case _ => Some( (l.init, l.last) )
}
}
@Vassil. You are correct my examples do not cover all the possible cases. If you are using this example in real-life you need to add the rest of the cases to make the match block complete.
ReplyDeleteHi there, awesome site. I thought the topics you posted on were very interesting. I tried to add your RSS to my feed reader
ReplyDeleteand it a few. take a look at it, hopefully I can add you and follow.
Extractors
Thanks for sharing your ideas and thoughts, i like your blog and bookmark this blog for further use thanks again…
ReplyDeleteExtractors
As a newcomer to the scala lang I've found these daily posts a great resource for learning. Thanks for them!
ReplyDeleteJust minor note to the last example, I suppose that if you use an operator form "head X tail" the name of X plays role in precedence (rules for expressions apply) and that's why in
case List(1, 2, 3, 4, 5, 6, 7) ::> 8 ::> 9
leftmost ::> takes precedence (because the name ends with >), whereas in
case 1 :: 2 :: List(3, 4, 5, 6, 7, 8)
rightmost :: takes precedence (because the name ends with :)