val xs = 58 #:: 43 #:: 93 #:: Stream.empty
xs match {
case first #:: second #:: _ => first - second
case _ => -1
}
where the extractor is defined this way:
object #:: {
def unapply[A](xs: Stream[A]): Option[(A, Stream[A])] =
if (xs.isEmpty) None
else Some((xs.head, xs.tail))
}
Given this I wanted to try an extractor on the Rational number samples from the Scala by Example book, this is how the Rational number looks:
class Rational(n: Int, d: Int) {
private def gcd(x: Int, y: Int): Int = {
if (x == 0) y
else if (x < 0) gcd(-x,y)
else if (y < 0) -gcd(x, -y)
else gcd(y % x, x)
}
private val g = gcd(n, d)
val numer: Int = n/g
val denom: Int = d/g
def +(that: Rational) =
new Rational(numer * that.denom + that.numer * denom,
denom * that.denom)
def -(that: Rational) =
new Rational(numer * that.denom - that.numer * denom,
denom * that.denom)
def *(that: Rational) =
new Rational(numer * that.numer, denom * that.denom)
def /(that: Rational) =
new Rational(numer * that.denom, denom * that.numer)
override def toString = "" + numer + "/" + denom + ""
def square = new Rational(numer*numer, denom*denom)
}
and I wanted an extractor which would behave the following way:
val r = new Rational(2, 3)
r match {
case num / denom => num + "/" + denom
}
This is absolutely feasible in Scala given the flexibility in the names of identifiers. Given this an extractor called "/" can be defined the following way:
object / {
def unapply(r: Rational): Option[(Int, Int)] = Some(r.numer, r.denom)
}
and used for extracting the numerator and denominator of the rational number!
r match {
case /(num, denom) => num + "/" + denom
}
//using infix
r match {
case num / denom => num + "/" + denom
}
No comments:
Post a Comment