Skip to content

Instantly share code, notes, and snippets.

@takkkun
Created July 22, 2016 09:21
Show Gist options
  • Save takkkun/68ff3f2a70e86fb9379307ac76c257ab to your computer and use it in GitHub Desktop.
Save takkkun/68ff3f2a70e86fb9379307ac76c257ab to your computer and use it in GitHub Desktop.
// IDみたいな仕組みがあって
trait Identifier[A] {
val value: A
}
case class UserId(value: UUID) extends Identifier[UUID]
case class GroupId(value: UUID) extends Identifier[UUID]
// またそれとは別にConverterという型クラスがあって
trait Converter[A, B] {
def apply(obj: A): B
}
// UserIdやGroupIdをStringに変換する型クラスのインスタンスを定義するとき
implicit object UserIdToStringConverter extends Converter[UserId, String] {
def apply(userId: UserId) = userId.value.toString
}
implicit object GroupIdToStringConverter extends Converter[GroupId, String] {
def apply(groupId: GroupId) = groupId.value.toString
}
// 上記のようにいちいち各*Idごとに変換を定義するのはめんどくさい。
// *Id(Identifier[UUID]を継承したもの)は一律こう変換してしまえ。
implicit object UUIDIdentifierToStringConverter extends Converter[Identifier[UUID], String] {
def apply(id: Identifier[UUID]) = id.value.toString
}
// でもこれ出来ない。ConverterのAが非変なので。
// ConverterのAを反変にすればConverter[Identifier[UUID], String]がConverter[UserId, String]やConverter[GroupId, String]に
// 変化できるので、OKになる。ついでに戻り値は共変にしておく。
trait Converter[-A, +B] {
def apply(obj: A): B
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment