高卒文系Scala vol.15 - Rational写経 -

コメントとか変数名とか、おかしいけど気にしない。

Rational定義

/*
* Rational.scala
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package sample.vo

/**
* 分数を表すクラス。
*
* @author zetta1985
*
* @param n 分子
* @param d 分母
* @throw IllegalArgumentException denominatorが0の場合
*/
class Rational private(n: Int, d: Int) {
  require(d != 0)

  /** 最大公約数 */
  private val gratestCommonDiviser = getGratestCommonDiviser(n.abs, d.abs);

  /** 分子 */
  val numerator: Int = n / gratestCommonDiviser

  /** 分母 */
  val denominator: Int  = d / gratestCommonDiviser

  def this(n: Int) = this(n, 1)

  /** 指定されたRationalをこのRationalに加算した値を返す。 */
  def + (that: Rational): Rational =
    new Rational(
      numerator * that.denominator + that.numerator * denominator,
      denominator * that.denominator
    )

  /** 指定されたRationalをこのRationalに加算した値を返す。 */
  def + (num: int): Rational =
    new Rational(numerator + num * denominator, denominator)

  /** 指定されたRationalをこのRationalに減算した値を返す。 */
  def - (that: Rational): Rational =
    new Rational(
      numerator * that.denominator - that.numerator * denominator,
      denominator * that.denominator
    )

  /** 指定されたRationalをこのRationalに減算した値を返す。 */
  def - (num: Int): Rational =
    new Rational(numerator - num * denominator, denominator)

  /** 指定されたRationalをこのRationalに乗算した値を返す。 */
  def * (that: Rational): Rational =
    new Rational(numerator * that.numerator, denominator * that.denominator)

  /** 指定されたRationalをこのRationalに乗算した値を返す。 */
  def * (num: Int): Rational =
    new Rational(numerator * num, denominator)

  /** 指定されたRationalをこのRationalに除算した値を返す。 */
  def / (that: Rational): Rational =
    new Rational(numerator * that.denominator, denominator * that.numerator)

  /** 指定されたRationalをこのRationalに除算した値を返す。 */
  def / (num: Int): Rational =
    new Rational(numerator, denominator * num)

  /** このRationalの文字列表現を返す。 */
  override def toString = numerator + "/" + denominator

  // aとbの最大公約数を返す。
  private def getGratestCommonDiviser(a: Int, b: Int): Int =
    if (b == 0) a else getGratestCommonDiviser(b, a % b)
}

/**
* Rationalのコンパニオンオブジェクト
*/
object Rational{
  /** factoryメソッド */
  def apply(n: Int, d: Int): Rational = new Rational(n, d)
  def apply(n: Int): Rational = new Rational(n)

  /** 暗黙の型変換 */
  implicit def intToRational(num: Int) = new Rational(num)
}

エントリーポイント

/*
* Main.scala
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package sample
import sample.vo._
import sample.vo.Rational._

object Main extends Application{
  val r = Rational(4, 10)
  println(r)
  println
  println(r + Rational(3, 10))
  println(r + 3)
  println
  println(r - Rational(1, 3))
  println(r - 2)
  println
  println(r * Rational(2, 3))
  println(r * 5)
  println
  println(r / Rational(1, 4))
  println(r / 4)
  println
  println(2 * r)  // ここでコンパイルエラー
}

スタックトレース

(なんか余計なエラーが出てる気がするけど、キニシナイ)

init:
deps-jar:
Compiling 3 source files to D:\Scala\workspace\Sample\build\classes
D:\Scala\workspace\Sample\src\sample\Main2.scala:30: error: overloaded method value * with alternatives (Double)Double <and> (Float)Float <and> (Long)Long <and> (Int)Int <and> (Char)Int <and> (Short)Int <and> (Byte)Int cannot be applied to (sample.vo.Rational)
val r2 = 2 * r
one error found
D:\Scala\workspace\Sample\nbproject\build-impl.xml:229: Compile failed; see the compiler error output for details.
at scala.tools.ant.Scalac.error(Scalac.scala:451)
at scala.tools.ant.FastScalac.execute(FastScalac.scala:97)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
at sun.reflect.GeneratedMethodAccessor243.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:62)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
at sun.reflect.GeneratedMethodAccessor243.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.taskdefs.MacroInstance.execute(MacroInstance.java:394)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
at sun.reflect.GeneratedMethodAccessor243.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.Target.execute(Target.java:357)
at org.apache.tools.ant.Target.performTasks(Target.java:385)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1337)
at org.apache.tools.ant.Project.executeTarget(Project.java:1306)
at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
at org.apache.tools.ant.Project.executeTargets(Project.java:1189)
at org.apache.tools.ant.module.bridge.impl.BridgeImpl.run(BridgeImpl.java:278)
at org.apache.tools.ant.module.run.TargetExecutor.run(TargetExecutor.java:497)
at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:151)
D:\Scala\workspace\Sample\nbproject\build-impl.xml:405: The following error occurred while executing this line:
D:\Scala\workspace\Sample\nbproject\build-impl.xml:229: Compile failed because of an internal compiler error (Compile failed; see the compiler error output for details.); see the error output for details.
構築失敗 (合計時間: 2 秒)

追記 20091127

fscのキャッシュで残ってたMain2.scalaが原因でした。

スタックトレースをよく見てみると、Main.scalaではなくMain2.scalaでコンパイルエラーを起こしてました。

Rational.scala、Main.scalaのコードには問題無し。

fsc -resetでキャッシュをクリアして、再ビルドしたら上手く行きました。

id:yuroyoroさん、ありがとうございました><

このエントリーをはてなブックマークに追加
comments powered by Disqus