`constValue`, Tuples, and singleton types

Hello,
While reading the api page for scala.compiletime, I was surprised to find constValueTuple.
Which seems to exist as a consequence of tuples of constant types not being themselves constant types. ( for example constValue[(1,2)] fails with not a constant type )

As a consequence, since constValueTuple calls constValue on the tuple’s element, things like constValueTuple[( (1,2), (3,4) )] fail.
And more broadly, given a type that is either a constant type or a “constant tuple”, there is no simple way to constValue it.
There is also no equivalent to constValueOpt for tuples.

Hence my questions:

  • Why are tuples of constant types not also constant types ?
  • Should constValue cheat, and work anyways on cases where constValueTuple succeeds ?
  • Should constValueOpt cheat, and return Some on cases where constValueTuple succeeds ?
  • Should constValueTuple use a special “union” of constValue and constValueTuple for the elements instead ?
2 Likes

While I agree that tuples of all constant types not themselves being considered constant types is annoying, it’s not that bad to work around. Here’s a simple function that does what you want (works with the example you provided). A similar function could probably be made for opt, in case parts of the type passed in is not constant.

inline def constValueAll[A]: A = 
  inline erasedValue[A] match 
    case _: *:[h, t] => (constValueAll[h] *: constValueAll[t]).asInstanceOf[A]
    case _: EmptyTuple => EmptyTuple.asInstanceOf[A]
    case _ => constValue[A]

Thank you for the implementation !

However I was more curious of the reasons behind this oddity, rather than experiencing it as a problem (as I’ve not yet tried the new Tuple types)

constValue only matches types that are internally represented as ConstantType - I guess it is good as an atomic operation to build others on top of

1 Like