Skip to content

Instantly share code, notes, and snippets.

@kmizu
Last active May 20, 2017 00:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmizu/20557ecd2c12a5d7e77d127ef2f10413 to your computer and use it in GitHub Desktop.
Save kmizu/20557ecd2c12a5d7e77d127ef2f10413 to your computer and use it in GitHub Desktop.
Scalaで型クラスを使おう! ref: http://qiita.com/kmizu/items/b656d8cf45abc442598a
List(1, 2, 3).sum // => 6
class Rational(n: Int, d: Int) {
private[this] val g = gcd(n.abs, d.abs)
val numer = n / g
val denom = d / g
def this(n: Int) = this(n, 1)
def unary_- : Rational = new Rational(-numer, denom)
def negative: Boolean = numer < 0
def positive: Boolean = numer > 0
def + (that: Rational): Rational = {
new Rational(
numer * that.denom + that.numer * denom,
denom * that.denom
)
}
def + (i: Int): Rational = {
new Rational(numer + i * denom, denom)
}
def - (that: Rational): Rational = {
new Rational(
numer * that.denom - that.numer * denom,
denom * that.denom
)
}
def - (i: Int): Rational = {
new Rational(numer - i * denom, denom)
}
def * (that: Rational): Rational = {
new Rational(numer * that.numer, denom * that.denom)
}
def * (i: Int): Rational = {
new Rational(numer * i, denom)
}
def / (that: Rational): Rational = {
new Rational(numer * that.denom, denom * that.numer)
}
def / (i: Int): Rational = {
new Rational(numer, denom * i)
}
override def equals(that: Any): Boolean = that match {
case that:Rational => this.numer == that.numer && this.denom == that.denom
case _ => false
}
override def toString = numer +"/"+ denom
private[this] def gcd(a: Int, b: Int): Int = {
if (b == 0) a else gcd(b, a % b)
}
}
def sum[B >: A](implicit num: Numeric[B]): B
object Rational {
implicit object NumericRational extends Numeric[Rational] {
override def plus(x: Rational, y: Rational): Rational = x + y
override def minus(x: Rational, y: Rational): Rational = x - y
override def times(x: Rational, y: Rational): Rational = x * y
override def negate(x: Rational): Rational = -x
override def fromInt(x: Int): Rational = new Rational(x, 1)
override def toInt(x: Rational): Int = x.numer / x.denom
override def toLong(x: Rational): Long = toInt(x).toLong
override def toFloat(x: Rational): Float = (x.numer.toFloat / x.denom)
override def toDouble(x: Rational): Double = (x.numer.toDouble / x.denom)
override def compare(x: Rational, y: Rational): Int = {
val r = (x - y)
if(r.negative) -1 else if (r.positive) 1 else 0
}
}
}
assert(List(new Rational(1, 3), new Rational(1, 4), new Rational(1, 5)).sum == new Rational(47, 60))
assert(List(new Rational(1, 3), new Rational(1, 4), new Rational(1, 5)).product== new Rational(1, 60))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment