zio/zio-prelude
NewTypes 과 Equal 을 활용한 객체 비교
wefree
2021. 9. 23. 23:25
문제
다음과 같이 Site, bookSite, newsSite 를 정의할 때
final case class Site(domain: String, url: String)
val bookSite = Site("naver.com", "http://book.naver.com")
val newsSite = Site("naver.com", "http://news.naver.com")
bookSite 와 newsSite 를
- domain 기준으로 비교하면 같다.
- url 기준으로 비교하면 다르다.
domain 과 url 기준으로 각각 비교하는 method 를 아래처럼 추가할 수 있지만
final case class Site(domain: String, url: String) {
def equalByDomain(other: Site): Boolean = domain == other.domain
def equalByUrl(other: Site): Boolean = url == other.url
}
zio-prelude 의 NewTypes 와 Equal 을 사용해 구현해 보도록 한다. (이렇게 구현하면 어떤 장점이 있을까?)
코드
import zio.prelude.{Equal, EqualOps, Subtype}
object EqualTest {
final case class Site(domain: String, url: String)
object EqualByDomain extends Subtype[Site] {
implicit val equalByDomain = new Equal[EqualByDomain] {
override protected def checkEqual(l: EqualByDomain, r: EqualByDomain): Boolean =
l.domain == r.domain
}
}
type EqualByDomain = EqualByDomain.Type
object EqualByUrl extends Subtype[Site] {
implicit val equalByUrl: Equal[EqualByUrl] =
(l: EqualByUrl, r: EqualByUrl) => l.url == r.url
}
type EqualByUrl = EqualByUrl.Type
def main(args: Array[String]): Unit = {
val bookSite = Site("naver.com", "http://book.naver.com")
val newsSite = Site("naver.com", "http://news.naver.com")
val byDomain = EqualByDomain(bookSite) === EqualByDomain(newsSite)
println(byDomain) // true
val byUrl = EqualByUrl(bookSite) === EqualByUrl(newsSite)
println(byUrl) // false
}
}