Last active
June 14, 2017 21:19
-
-
Save marinho/42506e1808d64e76a419b2a3a9ae7edf to your computer and use it in GitHub Desktop.
Playing with implicit conversions and infix in Scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import scala.language.implicitConversions | |
| import scala.language.postfixOps | |
| // numerator | |
| // ( numerator ÷ denominator ) create a fraction object as ----------- | |
| // denominator | |
| object Main extends App { | |
| implicit def intToFraction(i: Int) = new IntWithFraction(i) | |
| // random examples | |
| println(5 ÷ 10) | |
| println(5 ÷ 10 simplify) | |
| println((1 ÷ 2) + (2 ÷ 4) - (3 ÷ 10) simplify) | |
| println((1 ÷ 2) * (2 ÷ 4)) | |
| println((8 ÷ 2) / (2 ÷ 1)) | |
| // all operations | |
| println((8 ÷ 2) + (2 ÷ 1)) | |
| println((8 ÷ 2) - (2 ÷ 1)) | |
| println((8 ÷ 2) * (2 ÷ 1)) | |
| println((8 ÷ 2) / (2 ÷ 1)) | |
| // division by zero | |
| try { | |
| println((8 ÷ 0)) | |
| } catch { | |
| case e: Exception => println("8 ÷ 0 => " + e) | |
| } | |
| // recursive operation and string formatting | |
| val result = List(1 ÷ 2, 2 ÷ 4, 3 ÷ 6, 4 ÷ 8).reduceLeft(_ + _) | |
| val simplified = result.simplify | |
| println(s"$result = $simplified") | |
| // operations with integers | |
| println((8 ÷ 2) + 2) | |
| println((8 ÷ 2) - 2) | |
| println((8 ÷ 2) * 2) | |
| println((8 ÷ 2) / 2) | |
| // mixed number | |
| println(10 ÷ 3 mixed) | |
| } | |
| class IntWithFraction(i: Int) { | |
| // http://www.fileformat.info/info/unicode/char/00f7/index.htm | |
| def ÷(denominator: Int) = new Fraction(i, denominator) | |
| } | |
| class Fraction(val numerator: Int, val denominator: Int) { | |
| override def toString = s"$numerator ÷ $denominator" | |
| if (denominator == 0) | |
| throw new Exception("Denominator cannot be zero") | |
| def +(other: Any) = plusOrMinus(this, other, 1) | |
| def -(other: Any) = plusOrMinus(this, other, -1) | |
| def *(other: Any) = other match { | |
| case x: Int => new Fraction(this.numerator * x, | |
| this.denominator) | |
| case x: Fraction => new Fraction(this.numerator * x.numerator, | |
| this.denominator * x.denominator) | |
| } | |
| def /(other: Any) = other match { | |
| case x: Int => new Fraction(this.numerator, | |
| this.denominator * x) | |
| case x: Fraction => new Fraction(this.numerator * x.denominator, | |
| this.denominator * x.numerator) | |
| } | |
| def simplify = { | |
| val minor = math.min(numerator, denominator) | |
| def findMaxDivisor(divisor: Int): Int = { | |
| if (numerator % divisor == 0 && denominator % divisor == 0) | |
| divisor | |
| else | |
| findMaxDivisor(divisor - 1) | |
| } | |
| val maxDivisor = findMaxDivisor(minor) | |
| new Fraction(numerator / maxDivisor, denominator / maxDivisor) | |
| } | |
| def mixed = { | |
| val integer = this.numerator / this.denominator | |
| val rest = new Fraction(this.numerator % this.denominator, this.denominator) | |
| (integer, rest) | |
| } | |
| private def plusOrMinus(a: Fraction, other: Any, operation: Int): Fraction = { | |
| def inner(b: Fraction) = { | |
| val numeratorA = a.numerator * b.denominator | |
| val numeratorB = b.numerator * a.denominator | |
| val denominator = a.denominator * b.denominator | |
| new Fraction(numeratorA + numeratorB * operation, denominator) | |
| } | |
| other match { | |
| case x: Int => inner(new Fraction(x, 1)) | |
| case x: Fraction => inner(x) | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment