Skip to content

Instantly share code, notes, and snippets.

@kijuky
Created August 7, 2011 09:40
Show Gist options
  • Save kijuky/1130245 to your computer and use it in GitHub Desktop.
Save kijuky/1130245 to your computer and use it in GitHub Desktop.
scalaのmatchでイレイジャと戯れる
import javax.measure.Measurable
import javax.measure.quantity.Quantity
import javax.measure.unit.Unit
// 任意の型からMeasurable[Q]を作る…前にargにMeasurable[Q]が渡されたときを考える。
def toMeasurable[Q <: Quantity](arg: Any)(implicit manifest: ClassManifest[Q]): Measurable[Q] = {
arg match {
case measurable: Measurable[_] =>
try {
// measurable の型パラメータが正しいことを保証するために
// 要求されたクォンティティ Q と次元が等しいかどうかをチェック
// (次元が等しければ、Q の単位に変換できる)
val unit = manifest.erasure.getField("UNIT").get(null).asInstanceOf[Unit[Q]]
measurable.doubleValue(unit) // コンパイルエラー。Measurable#doubleValue(v: _)を呼び出せない
} catch {
// 次元が等しくなかった場合
case illegalQuantity: ConversionException =>
throw new IllegalArgumentException(illegalQuantity)
}
measurable // コンパイルエラー。Measurable[_] は Measurable[Q] ではない。
}
}
// 型パラメータが _ である measurable は、
// その型パラメータを使っているメソッド doubleValue を呼び出せない。
// なので…
def toMeasurable[Q <: Quantity](arg: Any)(implicit manifest: ClassManifest[Q]): Measurable[Q] = {
arg match {
case measurable: Measurable[Q] => // 警告: イレイジャにより型情報がなくなる
try {
val unit = manifest.erasure.getField("UNIT").get(null).asInstanceOf[Unit[Q]]
measurable.doubleValue(unit)
} catch {
case illegalQuantity: ConversionException =>
throw new IllegalArgumentException(illegalQuantity)
}
measurable
}
}
// パターンマッチに Measurable[Q] を書くと警告が出る。
// この警告を出さないようにするには、キャストする。
def toMeasurable[Q <: Quantity](arg: Any)(implicit manifest: ClassManifest[Q]): Measurable[Q] = {
arg match {
case measurable: Measurable[_] =>
val measurableQ = measurable.asInstanceOf[Measurable[Q]]
try {
val unit = manifest.erasure.getField("UNIT").get(null).asInstanceOf[Unit[Q]]
measurableQ.doubleValue(unit) // OK
} catch {
case illegalQuantity: ConversionException =>
throw new IllegalArgumentException(illegalQuantity)
}
measurableQ
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment