Pattern Match on Case Objects with Type Members

后端 未结 2 2163
南方客
南方客 2021-02-08 12:18

Scala has a nice feature to infer type parameter inside the pattern match. It also checks pattern match exhaustiveness. For example:

sealed trait PField[T]

cas         


        
2条回答
  •  盖世英雄少女心
    2021-02-08 12:47

    This solution is a simplified version of solution posted by @Andrey Tyukin. He stated that

    it does not hold that a.T = b.T for any two values a, b of type Field3.

    It means that, to have exhaustive pattern match, type members must be ignored. So in order to have both exhaustiveness and type inference we need sealed hierarchy with type parameters.

    He suggested to create separate hierarchy of case classes and pattern match on them instead of on the main hierarchy. However in my case it can be simplified: I created new sealed trait with type parameter but the same case objects are used for pattern match ("unique guarantee" is held in the object itself). This is final solution:

    sealed trait Field {
      type T
      def ug: TField[T]
    }
    
    sealed trait TField[G] extends Field {
      type T = G
      def ug: TField[T] = this
    }
    
    case object Field1 extends TField[String]
    case object Field2 extends TField[Int]
    
    def getValue[X](f: Field {type T = X}): X = (f.ug: TField[X]) match {
      case Field1 => "abc"
      case Field2 => 123
    }
    

    Thanks to that I can use Field trait to define type classes without going into higher kinded types and switch into TField[G] for pattern match.

提交回复
热议问题