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