ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • NewTypes 과 Equal 을 활용한 객체 비교
    zio/zio-prelude 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 의 NewTypesEqual 을 사용해 구현해 보도록 한다. (이렇게 구현하면 어떤 장점이 있을까?)

     

    코드

    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
      }
    }

    'zio > zio-prelude' 카테고리의 다른 글

    ZIO prelude 의 Reader Monad  (0) 2022.07.24
    Functional Effect 의 다양한 합성(composition)  (0) 2021.10.10
    ZIO prelude 의 State Monad  (0) 2021.09.26

    댓글

Designed by Tistory.