-
sealed trait typeclassscala/basic 2022. 3. 29. 14:45
문제
sealed trait 대상으로 typeclass 를 정의할 때, 다음과 같은 문제가 있다.
https://www.reddit.com/r/scala/comments/96woxd/how_to_implement_an_adt_that_all_members_have/
코드
http://eed3si9n.com/herding-cats/typeclasses-102.html 참고
trait Eq[A] { def eqv(x: A, y: A): Boolean } object Eq { def apply[A](implicit eq: Eq[A]): Eq[A] = eq implicit class EqSyntax[A](x: A) { def ===(y: A)(implicit eq: Eq[A]): Boolean = eq.eqv(x, y) } } sealed trait TrafficLight object TrafficLight { def red: TrafficLight = Red def yellow: TrafficLight = Yellow def green: TrafficLight = Green case object Red extends TrafficLight case object Yellow extends TrafficLight case object Green extends TrafficLight } object MyTest { def main(args: Array[String]): Unit = { implicit val trafficLightEq: Eq[TrafficLight] = new Eq[TrafficLight] { override def eqv(x: TrafficLight, y: TrafficLight): Boolean = x == y } import Eq._ TrafficLight.Red === TrafficLight.Yellow // ERROR !!! TrafficLight.red === TrafficLight.yellow // OK } }
설명
TrafficLight.Red === TrafficLight.Yellow 일 때, ERROR 인 것은 implicit Eq[TrafficLight] 가 정의되었지만, implicit Eq[TrafficLight.Red] 는 정의되지 않은 상태이기 때문이다. 그래서 TrafficeLight.Red 를 TrafficLight 타입으로 처리할 수 있도록 def red: TrafficLight = Red 로 helper function 을 정의해 사용했다. http://eed3si9n.com/herding-cats/typeclasses-102.html 에도 잘 설명이 되어있다. 이런 번거로움 때문인지 zio-prelude Equal 에서는 contravariant 타입인 Equal[-A] 로 정의했다.
'scala > basic' 카테고리의 다른 글
Scala Closure (0) 2022.10.21 java callback 을 scala Future 로 바꾸기 (0) 2022.07.16 scala 에서 retry 구현하기 (0) 2021.11.25 scala enumeratum enum 사용하기 (0) 2021.11.13 Variance 문제 (3) 2021.10.22