Skip to content

Instantly share code, notes, and snippets.

@j5ik2o
Created January 1, 2012 06:33
Show Gist options
  • Save j5ik2o/1546494 to your computer and use it in GitHub Desktop.
Save j5ik2o/1546494 to your computer and use it in GitHub Desktop.
エンティティ・トレイトに対して Scalazの EqualとShowを実装するにはどうするべきか
package base
import scalaz._
import Scalaz._
/**
* エンティティを表すトレイト。
*
* @author j5ik2o
*/
trait Entity[ID <: java.io.Serializable] {
/**エンティティの識別子。*/
val identity: Identity[ID]
/**
* ハッシュコードを返す。
*
* @return ハッシュコード
*/
override final def hashCode: Int = identifier.hashCode
/**
* 指定されたオブジェクトと等価であるかを判定する。
*
* @param that オブジェクト
* @return 等価である場合はtrue
*/
override final def equals(that: Any): Boolean = that match {
case that: Entity[_] => identifier == that.identifier
case _ => false
}
}
// --- 実装側
pakcage test
class Employee(val identity: Identity[UUID], val name: String) extends Entity[UUID]
// このようにすればよいことはわかっているができれば、baseパッケージ側でimplicit parameterを定義することはできないか。
implicit val equalEntity: Equal[Employee] = equalA
implicit val showEntity: Show[Employee] = shows(_.toString)
val id = Identity(UUID.randomUUID)
val e1 = new Employee(id, "KATO")
val e2 = new Employee(id, "kato")
e1.shows
assert(e1 === e2)
// --- 以下のようにしてもimplicit parameter を探索できない。面倒だけどEmployee側に定義してあげないとだめかなー。
package base
object Implicits {
implicit def equalEntity[E <: Entity[ID], ID <: java.io.Serializable]: Equal[E] = equalA[E]
implicit def showEntity[E <: Entity[ID], ID <: java.io.Serializable]: Show[E] = shows(_.toString)
}
package test
import base.Implicits._
val id = Identity(UUID.randomUUID)
val e1 = new Employee(id, "KATO")
val e2 = new Employee(id, "kato")
e1.shows
// error: could not find implicit value for parameter s: scalaz.Show[test.Employee]
assert(e1 === e2)
// error: could not find implicit value for parameter e: scalaz.Equal[test.Employee]
// --- とりあえずこういう解決方法
package base
object Implicits {
implicit def equalEntity[ID <: java.io.Serializable]: Equal[Entity[ID]] = equalA
implicit def showEntity[ID <: java.io.Serializable]: Show[Entity[ID]] = shows(_.toString)
}
package test
import base.Implicits._
val id = Identity(UUID.randomUUID)
val e1: Entity[UUID] = new Employee(id, "KATO")
val e2: Entity[UUID] = new Employee(id, "kato")
e1.shows
assert(e1 === e2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment