トランプを表現するクラスを書いてみた。
こんな書き方できんのかよ...
Hello.scala
package example
import example.Suits._
import example.ValueHolder._
object Hello {
    def main(args: Array[String]) = {
        println(Ace of Spades)      // すごい
        println(2 of Diamonds)      // とてもすごい
    }
}
sealed trait Suits {
    def emoji: String
}
object Suits {
    object Diamonds extends Suits {
        override def emoji: String = "♦"
    }
    object Clubs extends Suits {
        override def emoji: String = "♣"
    }
    object Hearts extends Suits {
        override def emoji: String = "♥"
    }
    object Spades extends Suits {
        override def emoji: String = "♠"
    }
}
case class Card(
    val suits: Suits,
    val number: Int
) {
    override def toString(): String = {
        val numberString = number match {
            case 1  => "A"
            case 11 => "J"
            case 12 => "Q"
            case 13 => "K"
            case _  => number.toString()
        }
        s"(${suits.emoji},$numberString)"
    }
}
abstract class ValueHolder {
    val value: Int
    def of(suits: Suits): Card = Card(suits, value)
}
object ValueHolder {
    object Ace extends ValueHolder {
        override val value: Int = 1
    }
    implicit class IntValueHolder(override val value: Int)
        extends ValueHolder {}
}
出力
(♠,A)
(♦,2)
※「ハートの2000」みたいなカードを生成できる点はご愛嬌
解説
abstract class ValueHolder {
    val value: Int
    def of(suits: Suits): Card = Card(suits, value)
}
を実装すると以下のように書けるようになる。
val v: ValueHolder = ??? // なんかうまいこと ValueHolder のインスタンスを生成する
val card = v.of(Spades)
Scalaは特定の条件を満たすとメソッド呼び出しの「.」を省略してスペースで代用できる(らしい)し、引数が1つのメソッドは引数を括弧でくくる代わりにスペースで代用できる(らしい)ので、以下のように書ける。
val card = v of Spades
さらに
implicit class IntValueHolder(override val value: Int)
        extends ValueHolder {}
によって、IntをValueHolderとして扱うことができるようになるので、
val card = 2 of Diamonds
と書ける。
