Friday, October 16, 2015

Scala extractors

Here is the code:

    object Twice {
      def apply(x: Int) = x * 2
      def unapply(x: Int) = if(x % 2 == 0) Some(x / 2) else None
    }
    // outside pattern mathcing, Twice.apply(21) is called
    val x = Twice(21)
    x match {
        // inside pattern matching, Twice.unapply(x) is called,
        // the result Some(21) is matched against y,
        // y gets the value 21
      case Twice(y) => println(x + " is twice " + y)
      case _ => println(x + " is odd.")
    }

Another example (matching Cartesian coordinates to polar coordinates):

    trait Complex
    case class Cart(re: Double, im: Double) extends Complex
    object Polar {
      def apply(mod: Double, arg: Double): Complex = new Cart(mod * Math.cos(arg), mod * Math.sin(arg))
      def unapply(z: Complex): Option[(Double, Double)] = {
        z match {
          case Cart(re, im) =>
            val at = Math.atan(im / re)
            Some(Math.sqrt(re * re + im * im), if(re < 0) at + Math.PI else if(im < 0) at + 2 * Math.PI else at)
        }
      }
    }
    val x1 = Cart(1.0, 1.0)
    x1 match {
      case Polar(r, theta) => println("Radius: %.3f, Angle: %.3f".format(r, theta))
    }

0 comments: