Skip to content

No way to differentiate NamedTuple from other types #22422

@bishabosha

Description

@bishabosha

Assume you have a type level algorithm over named tuples that needs to recurse when the value type is a named tuple, otherwise do something else. (e.g. check a named tuple is substructually equivalent to another)

Currently there isn't a way to do that because you cannot differentiate named tuple from other types

Compiler version

3.6.3

Minimized code

Perhaps there is a better way, but for simplicity you can not use match types on their own because the upper bound of AnyNamedTuple is Any.

type IsNamedTuple[T] = T match
  case AnyNamedTuple => false
  case _             => true

val x: IsNamedTuple[NamedTuple.Empty] = true
val y: IsNamedTuple[(foo: Int)] = true
val z: IsNamedTuple[Int] = false // error
val q: IsNamedTuple[String] = false // error

Output

val z: IsNamedTuple[Int] = false // error
Found:    (false : Boolean)
Required: IsNamedTuple[Int]

Note: a match type could not be fully reduced:

  trying to reduce  IsNamedTuple[Int]
  failed since selector Int
  does not match  case NamedTuple.AnyNamedTuple => (true : Boolean)
  and cannot be shown to be disjoint from it either.
  Therefore, reduction cannot advance to the remaining case

    case _ => (false : Boolean)
val q: IsNamedTuple[String] = false // error
Found:    (false : Boolean)
Required: IsNamedTuple[String]

Note: a match type could not be fully reduced:

  trying to reduce  IsNamedTuple[String]
  failed since selector String
  does not match  case NamedTuple.AnyNamedTuple => (true : Boolean)
  and cannot be shown to be disjoint from it either.
  Therefore, reduction cannot advance to the remaining case

    case _ => (false : Boolean)

Expectation

the standard library could have a way to determine if a type is a match type or not, perhaps a primitive compile-time op?

object NamedTuple:
  type IsNamedTuple[T] <: Boolean

Another trick I wanted to try was if NamedTuple.From[T] would reduce or not, but again this isnt useful because NamedTuple.From[(foo: Int)] matches NamedTuple.From[t] and also NamedTuple[ns, vs] so cant be distinguished from a reduced or non-reduced form

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions