Search code examples
scalascala-3

How to type a tuple of any length but only having options in scala 3


How could I have something like

var tuple : (Option[Any]) | (Option[Any], Option[Any]) | (Option[Any], Option[Any], Option[Any]) | (Option[Any], Option[Any], Option[Any], Option[Any])  

But more elegantly?


Solution

  • You can do something like this in scala3.0:

    scala> type OptTuple[T <: Tuple] = T match
         |   case Option[_] *: t => OptTuple[t]
         |   case EmptyTuple => DummyImplicit
         |
    
    scala> case class MyTuple[T <: Tuple : OptTuple](tuple: T)
    // defined case class MyTuple
    
    scala> val t1 = MyTuple((Option(1), Option("a"), Option(3.0)))
    val t1: MyTuple[(Option[Int], Option[String], Option[Double])] = MyTuple((Some(1),Some(a),Some(3.0)))
    
    scala> val t2 = MyTuple((Option(1), Option("a"), 3.0))
    -- Error: ----------------------------------------------------------------------
    1 |val t2 = MyTuple((Option(1), Option("a"), 3.0))
      |                ^
      |     Match type reduction failed since selector  Double *: EmptyTuple.type
      |     matches none of the cases
      |
      |         case Option[_] *: t => OptTuple[t]
      |         case EmptyTuple => DummyImplicit
    1 error found