ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • typeclass
    scala/scala3 2024. 3. 22. 00:21

    공식문서: https://docs.scala-lang.org/scala3/reference/contextual/type-classes.html#

    (import 된 given 의 내부에 들어있는 extension method 는 자동으로 꺼내져 적용된다?)

    예제1

    case class Rect(width: Double, height: Double)
    case class Circle(radius: Double)
    
    trait Shape[A] {
      extension (a: A) {
        def area(): Double
      }
    }
    
    object Shape {
      // given listLast[T](using ...): Last[List[T]] = ... 형태로 사용도 가능 (generics 경우)
      given Shape[Rect] = new Shape[Rect] {
        extension (a: Rect) {
          def area(): Double = a.width * a.height
        }
      }
    
      given circleShape: Shape[Circle] = new Shape[Circle] {
        extension (a: Circle) {
          def area(): Double = 3.14 * a.radius * a.radius
        }
      }
    
      def isBig[A](a: A)(using Shape[A]): Boolean = if (a.area() < 100) false else true
    }
    
    @main def main(): Unit = {
      import Shape.given // 모든 given 을 import
    //  import Shape.circleShape  // 이름이 있는 given 의 경우 명시적으로 그것만 import
    //  import Shape.{given Shape[Circle], given Shape[Rect]}  // 이름이 없는 경우 type 으로 import
    
      val rect: Rect = Rect(2, 3)
      println(rect.area()) // 6.0
      println(Shape.isBig(rect)) // false
    
      val circle: Circle = Circle(10)
      println(circle.area()) // 314.0
      println(Shape.isBig(circle)) // true
    }

     

     

    예제2

    enum Fig2D {
      case Rect(w: Double, h: Double)
      case Circle(r: Double)
    }
    
    import Fig2D.*
    
    trait Shape[A] {
      extension (a: A) def area(): Double
    }
    
    object Shape {
      given Shape[Fig2D] = new Shape[Fig2D] {
        extension (shape: Fig2D) override def area(): Double = shape match {
          case Rect(w, h) => w * h
          case Circle(r) => r * r * 3.14
        }
      }
    }
    
    
    object Test {
      def main(args: Array[String]): Unit = {
        import Shape.given
    
        val rect: Fig2D = Rect(3, 4)
        val circle: Fig2D = Circle(2)
    
        println(rect.area())
      }
    }

    'scala > scala3' 카테고리의 다른 글

    Either using cats and ox  (0) 2024.04.04
    play-json 에서 scala3 enum 사용하기  (0) 2024.03.29
    Exports  (0) 2024.03.22
    opaque type  (0) 2024.03.22
    Function value signature for generics, context functions  (0) 2024.03.22

    댓글

Designed by Tistory.