Skip to content

Instantly share code, notes, and snippets.

@piyo7
Last active August 29, 2015 14:08
Show Gist options
  • Save piyo7/e208908e3ab6388cd956 to your computer and use it in GitHub Desktop.
Save piyo7/e208908e3ab6388cd956 to your computer and use it in GitHub Desktop.
型に数値を埋めこんでみよう ref: http://qiita.com/piyo7/items/5df3ad7e53216df5f65f
sbt.version = 0.13.6
name := "coin"
version := "1.0"
scalaVersion := "2.11.2"
libraryDependencies += "com.github.okomok" % "sing-core_2.11" % "0.2.0"
case class Coin(value: Int, num: Int) {
def +(a: Coin) = {
assert(value == a.value, "違う種類の硬貨を足しています")
Coin(value, num + a.num)
}
def -(a: Coin) = {
assert(value == a.value, "違う種類の硬貨を引いています")
Coin(value, num - a.num)
}
def sum = value * num
}
import com.github.okomok.sing.Dense
case class Coin[Value <: Dense] (value: Value, num: Int) {
def +(a: Coin[Value]) = Coin(value, num + a.num)
def -(a: Coin[Value]) = Coin(value, num - a.num)
def sum = value.unsing * num // unsingでsing.Denseをscala.Intに変換。
}
import com.github.okomok.sing.Dense
val a: Coin[Dense._5] = Coin(Dense._5, 2) + Coin(Dense._5, 4)
// val b = Coin(Dense._5, 3) - Coin(Dense._10, 6) // コンパイル不可
import com.github.okomok.sing.Dense
class Coin[Value <: Dense] private(val value: Value, val num: Int) {
def +(a: Coin[Value]) = new Coin(value, num + a.num)
def -(a: Coin[Value]) = new Coin(value, num - a.num)
def sum = value.unsing * num
}
object Coin {
type _1 = Coin[Dense._1]
def _1(num: Int) = new _1(Dense._1, num)
type _5 = Coin[Dense._5]
def _5(num: Int) = new _5(Dense._5, num)
type _10 = Coin[Dense._10]
def _10(num: Int) = new _10(Dense._10, num)
type _50 = Coin[Dense._50]
def _50(num: Int) = new _50(Dense._50, num)
// singはDense._XXを50以下までしか定義していないので、
// 自然数100を表す値と型を計算しておく。
private type Dense_100 = Dense._50#times[Dense._2]
private val Dense_100 = Dense._50.times(Dense._2)
type _100 = Coin[Dense_100]
def _100(num: Int) = new _100(Dense_100, num)
// 同様に、自然数500を表す値と型を計算しておく。
private type Dense_500 = Dense._50#times[Dense._10]
private val Dense_500 = Dense._50.times(Dense._10)
type _500 = Coin[Dense_500]
def _500(num: Int) = new _500(Dense_500, num)
}
val a: Coin._1 = Coin._1( 1) // 1 円 x 1
val b: Coin._5 = Coin._5( 2) // 5 円 x 2
val c: Coin._10 = Coin._10( 3) // 10 円 x 3
val d: Coin._50 = Coin._50( 4) // 50 円 x 4
val e: Coin._100 = Coin._100(5) // 100円 x 5
val f: Coin._500 = Coin._500(6) // 500円 x 6
val aa: Coin._1 = a + a
// val ab = a + b // コンパイル不可
val wallet: Seq[Coin[_]] = Seq(a, b, c, d, e ,f)
println(wallet.map(_.sum).sum) // 3741円
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment