This example uses Scala 2.8 which I believe is required.
Only two methods are focused on. PartialFunction.cond and PartialFunction.condOpt.
As per request the signature for said methods are:
- def cond[T](x: T)(pf: PartialFunction[T, Boolean]): Boolean
- def condOpt[T, U](x: T)(pf: PartialFunction[T, U]): Option[U]
Now for some examples:
- scala> import PartialFunction._
- import PartialFunction._
- scala> def strangeConditional(other: Any): Boolean = cond(other) {
- | case x: String if x == "abc" || x == "def" => true
- | case x: Int => true
- | }
- strangeConditional: (other: Any)Boolean
- scala> strangeConditional("abc")
- res0: Boolean = true
- scala> strangeConditional("hello")
- res1: Boolean = false
- scala> strangeConditional(3)
- res2: Boolean = true
- scala> def onlyInt(v: Any): Option[Int] = condOpt(v) { case x: Int => x }
- onlyInt: (v: Any)Option[Int]
- scala> onlyInt("hi")
- res3: Option[Int] = None
- scala> onlyInt(3)
- res4: Option[Int] = Some(3)
- scala> import util.control.Exception.catching
- import util.control.Exception.catching
- scala> object IntNum {
- | val number = catching(classOf[NumberFormatException])
- | def unapply(x : Any) = condOpt(x) {
- | case x : Int => x
- | case y : String if number.opt(y.toInt).isDefined => y.toInt
- | }
- | }
- defined module IntNum
- scala> 1 match { case IntNum(x) => println(x+" i win!")}
- 1 i win!
- scala> 3 match { case IntNum(x) => println(x+" i win!")}
- 3 i win!
It would be somewhat more useful to supply the type signatures of cond and condOpt, I think. It's not necessarily obvious what the utility of these are, particularly when using Any for your examples; or rather, it's not clear what advantage is gained over using a simple match expression.
ReplyDeleteobject IntNum {
ReplyDelete..val number = catching(classOf[NumberFormatException])
..def unapply(x: Any) = x match {
....case x: Int => Some(x)
....case x: String => number.opt(x.toInt)
...._ => None
..}
}
is easier to read IMHO and does not call y.toInt twice (using opt together with condOpt seems contraproductive to me)
(sorry for the dots -- I was not able to figure out how to indent as tags are not allowed and whitespace is removed or compressed)
Nice blog, btw. Keep up the good work!
Wasn't it meant to be
ReplyDeletescala> "3" match { case IntNum(x) => println(x+" i win!")}
3 i win!
?