【问题标题】:How Assigning TupleN value to *: type variable works in Scala 3?将 TupleN 值分配给 *: 类型变量如何在 Scala 3 中工作?
【发布时间】:2021-10-04 08:20:42
【问题描述】:

来自scala中的类型层次树

  • 让a:Tuple2[Int,Int],我知道Tuple2[Int,Int]Product2[Int,Int]延伸;
  • 让 b:1 *: 2 *: EmptyTuple 的类型为 Tuple(精化为 Int *: Int *: EmptyTuple

它们是不同的类型,没有任何父关系。他们唯一拥有的是Product,它们都是从Product扩展而来的。

但是我可以将a 分配给b 并且相反,为什么?

【问题讨论】:

    标签: scala scala-3 hlist dotty singleton-type


    【解决方案1】:

    它们是不同的类型,但这并不意味着它们不相关。 1 *: 2 *: EmptyTupleTuple2[Int,Int] 的子类型,因为单例文字 12Int 的子类型,而 Tuple2 的类型参数是协变的。

    您可以将1 *: 2 *: EmptyTuple 的实例扩展为Tuple2[Int,Int],但反之则不行。

    请注意Tuple2[A, B]A *: B *: EmptyTuple 是等价的。 1 *: 2 *: EmptyTuple 被假定为基于问题语法的类型级表达式,但如果它是一个值级表达式,那么它的类型将是 Int *: Int *: EmptyTuple,这将等同于 Tuple2[Int,Int]。在这种情况下,两种类型的实例都可以“分配”给彼此。

    参考代码:

    @main def main() =
      type T1 = Tuple2[Int, Int]
      type T2 = 1 *: 2 *: EmptyTuple
    
      val t1a: T1 = (1, 2) //compiles
      val t2a: T2 = (1, 2) //compiles
      val t1b: T1 = (2, 1) //compiles
    //  val t2b: T2 = (2, 1) // does not compile
    
    //  t1a: T2 //does not compile
      t2a: T1 //compiles
    
      summon[1 <:< Int] // compiles
    //  summon[1 =:= Int] // does not compile
      summon[T2 <:< T1] //compiles
    //  summon[T1 <:< T2] // does not compile
    //  summon[T1 =:= T2] // does not compile
    
      //these are the same types, not exclusively subtypes of one another
      summon[Tuple2[Int, Int] =:= Int *: Int *: EmptyTuple]
      summon[Tuple2[Int, Int] <:< Int *: Int *: EmptyTuple]
      summon[Int *: Int *: EmptyTuple <:< Tuple2[Int, Int]]
    

    【讨论】:

    • 我不认为@LinLee 指的是单例类型1 *: 2 *: EmptyTuple,我认为他只是指Int *: Int *: EmptyTuple
    • @MichaelZajac 是的,基于最有可能发生的结果,但是如果您要将 a:Tuple2[Int,Int]b:1 *: 2 *: EmptyTuple 进行比较,那将是类型之间的比较,并且在这两种情况下都是值会是一样的
    【解决方案2】:

    在 Scala 3 中,Tuple1...Tuple22 类型由编译器综合修改以扩展 *: 类型。即Tuple2[A, B]被修改为扩展A *: B *: EmptyTuple(扩展Tuple)。

    因此,您可以将Tuple2[Int, Int] 分配给Int *: Int *: EmptyTuple。同样,相反的情况也是可能的,因为A *: ... EmptyTuple 将尽可能被视为TupleN

    【讨论】:

    • 除了编译魔法没有别的原因
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    相关资源
    最近更新 更多