Search code examples
scalascala-3match-types

How to get match type with multiple type parameters to work correctly in Scala 3


I am trying to understand multiple types in Match type. Even though below works

type C2[N, M] = (N,M) match {
    case (String, Int) => Int 
    case (String, String) => Int 
    case (Int, String) => Int 
}
 
def fn[M,N](x:N,y:M):C2[N,M] = (x,y) match {
    case xx: (String, Int) @unchecked => xx(0).size + xx(1)
    case xx: (String, String) @unchecked => xx(0).size + xx(1).size
    case xx: (Int, String) @unchecked => xx(0) + xx(1).size
}

But i am unable to work below style eventhough Match type works OK

scala> type C2[N, M] = N match {
     |     case String => M match {
     |             case Int => Int
     |             }
     | }

scala> def fn[M,N](x:N,y:M):C2[x.type,y.type] = x match {
     |     case xx:String => y match {
     |             case yy:Int => (xx.size + yy)
     |             }
     | }
-- Error:
3 |            case yy:Int => (xx.size + yy)
  |                            ^^^^^^^^^^^^
  |                            Found:    Int
  |                            Required: (y : M) match {
  |                              case Int => Int
  |                            }

scala>

Solution

  • I got it working as following

    type C1Str[M] = M match {
        case Int => Int
        case String => Int
    }
    
    type C1Int[M] = M match {
        case String => Int
    }
    
    type C2[N, M] = N match {
      case String => C1Str[M]
      case Int => C1Int[M]
    }
     
    def fn[M,N](x:N,y:M):C2[N,M] = x match {
      case x: String => y match {
        case y: Int => x.size + y
        case y: String => x.size + y.size
      }
      case x: Int => y match {
        case y: String => x + y.size
      }
    }
    

    It looks if you want to create a match type with multiple type parameters you need to make each case another match type.