English 中文(简体)
设想3
原标题:Scala 3 generic tuples: type bound & converting to Seq

我认为,我有两个问题。

我想有一套标记类型,图形的所有内容至少在图萨拉3.3.1中是<代码>Animal。 下面是我来的:

// In ReproDef.scala
object ReproDef {
  type SubtypeTuple[T, L <: Tuple] <: Tuple = L match {
    case EmptyTuple => EmptyTuple
    case head *: tail => AsSubtype[T, head]#Out *: SubtypeTuple[T, tail]
  }

  class AsSubtype[T, U] {
    type Out = U
  }

  given [T, U <: T]: AsSubtype[T, U] = new AsSubtype[T, U]

  sealed trait Animal
  case class Cat() extends Animal
  case class Dog() extends Animal
  case class Bird() extends Animal

  val validTuple: SubtypeTuple[Cat | Dog | Bird, (Cat, Dog, Bird)] = Cat() *: Dog() *: Bird() *: EmptyTuple
  val validTuple2: SubtypeTuple[Animal, (Animal, Animal)] = (Cat(), Dog())
  val validTuple3: (Animal, Animal) = validTuple2

  def toSeq[L <: Tuple](tup: SubtypeTuple[Animal, L]): Seq[Animal] = {
    tup match {
      case empty: EmptyTuple => Seq.empty
      case (head: Animal) *: (tail: SubtypeTuple[Animal, tail_]) => head +: toSeq(tail)
    }
  }
}

(批量披露:我有不同的解决办法,但效果较差。) 以上法典是由ChatGPT产生的,但应当这样做。 我发现的错误至少是相同的。

Now here comes my first question: is there a better way to formulate this concept of a tuple where each element is at least a certain type T?

我的第二个问题是,我希望能够将只含有动物的les改成动物的 Se。 彩色类型包含一种<代码>toList方法,但有时只使用:

// In ReproUse.scala
def foo(): Unit = {
  val sig: (ReproDef.Cat, ReproDef.Dog) = (ReproDef.Cat(), ReproDef.Dog())
  def myId(x: Tuple): Tuple = x
  val x: Seq[ReproDef.Animal] = myId(sig).toList // Compiler error, see below
  println(myId(sig).toList) // Works, also without myId of course
}

相差错:

Found:    List[Tuple.Union[(?1 : Tuple)]]
Required: Seq[testdyn.ReproDef.Animal]

where:    ?1 is an unknown value of type Tuple


Note: a match type could not be fully reduced:

  trying to reduce  Tuple.Union[(?1 : Tuple)]
  trying to reduce  scala.Tuple.Fold[(?1 : Tuple), Nothing, [x, y] =>> x | y]
  failed since selector  (?1 : Tuple)
  does not match  case EmptyTuple => Nothing
  and cannot be shown to be disjoint from it either.
  Therefore, reduction cannot advance to the remaining case

    case h *: t => h | scala.Tuple.Fold[t, Nothing, [x, y] =>> x | y] [7:35]

为了避免这种类型的错误,我也界定了我自己的基调,见第一部法典。 然而,这还造成一种类型的错误:

// In ReproUse.scala
def bar(): Unit = {
  val sig: (ReproDef.Cat, ReproDef.Dog) = (ReproDef.Cat(), ReproDef.Dog())
  println(ReproDef.toSeq(sig))
}

错误:

Found:    (sig : (testdyn.ReproDef.Cat, testdyn.ReproDef.Dog))
Required: testdyn.ReproDef.SubtypeTuple[testdyn.ReproDef.Animal, L]

where:    L is a type variable with constraint <: Tuple


Note: a match type could not be fully reduced:

  trying to reduce  testdyn.ReproDef.SubtypeTuple[testdyn.ReproDef.Animal, L]
  failed since selector  L
  does not match  case EmptyTuple => EmptyTuple
  and cannot be shown to be disjoint from it either.
  Therefore, reduction cannot advance to the remaining case

    case head *: tail => testdyn.ReproDef.AsSubtype[testdyn.ReproDef.Animal, head]#Out *:
  testdyn.ReproDef.SubtypeTuple[testdyn.ReproDef.Animal, tail] [14:28]

My custom toSeq method does work in the file ReproDef.scala, the problem starts occurring only when I want to use that method outside the file.

I think I am simply getting confused where the boundary is for typechecking, and I am probably expecting too much. Can someone explain to me my oversight, and what kind of type annotations I have to add to get these small examples to compile? Or is there maybe a better match type I can use that Scala 3 can work with better? The main motivaiton for this question is that I will probably use this toSeq method quite a few times, so I d like it to cause as few type annotations as possible.

问题回答




相关问题
Having many stacks with different types

I m making a C program that needs to use two stacks. One needs to hold chars, the other needs to hold doubles. I have two structs, node and stack: struct node { double value; struct node *...

Creating (boxed) primitive instance when the class is known

I need a method that returns an instance of the supplied class type. Let s assume that the supplied types are limited to such that an "empty" instance of them can be created. For instance, supplying ...

How does php cast boolean variables?

How does php cast boolean variables? I was trying to save a boolean value to an array: $result["Users"]["is_login"] = true; but when I use debug the is_login value is blank. and when I do ...

How to generate an instance of an unknown type at runtime?

i ve got the following in C#: string typename = "System.Int32"; string value = "4"; theses two strings should be taken to generate an object of the specified type with the specified value... result ...

Type reference scope

I m studying databases and am currently working on a object-relational DB project and I ve encountered a small problem with the number of possible constraints in an object table. I m using "Database ...

热门标签