Scala递归类型

Scala递归类型,scala,types,Scala,Types,我只是想了解Scala的类型系统。我偶然发现了一个代码,看起来像这样: trait A extends Something { type X <: XLike trait XLike { this: X => .... .... } } trait A扩展了某些东西{ X型 .... .... } } 这意味着什么?在哪些情况下,我希望这样编码?我知道我是嵌套类型,但是像这样的嵌套类型并使用它来引用嵌套类型有什么好处呢?这个A#XLike特性不能在A

我只是想了解Scala的类型系统。我偶然发现了一个代码,看起来像这样:

trait A extends Something {
  type X <: XLike

  trait XLike { this: X =>
    ....
    ....
  }
}
trait A扩展了某些东西{
X型
....
....
}
}
这意味着什么?在哪些情况下,我希望这样编码?我知道我是嵌套类型,但是像这样的嵌套类型并使用它来引用嵌套类型有什么好处呢?

这个
A#XLike
特性不能在
A
中的任何地方混合:

val a = new A {}; import a._

scala> class KK extends XLike
<console>:21: error: illegal inheritance;
 self-type KK does not conform to a.XLike's selftype a.X
       class KK extends XLike
                        ^
甚至:

trait B extends A {type X = XLike}

val b = new B {}; import b._

scala> class KK extends XLike
defined class KK
因此,它允许您选择必须融入的特征:

trait B extends A {
  type X = XImpl1      
  trait XImpl1 extends XLike { this: X => }
  trait XImpl2 extends XLike { this: X => }
}

val b = new B {}; import b._

scala> class ZZ extends XImpl1
defined class ZZ

scala> class ZZ extends XImpl2
<console>:40: error: illegal inheritance;
 self-type ZZ does not conform to b.XImpl2's selftype b.XImpl2 with b.X
       class ZZ extends XImpl2
                        ^
scala> class ZZ extends XImpl1 with XImpl2 // XImpl2 still can be mixed but only if XImpl1 present in linearization
defined class ZZ
如果您将
Group0
更改为
Group2
,您可能会失去
MandatoryHandler2
(例如,可能是某个reporter)

另一个:库开发人员可能会提供许多简洁的特性,但其中一些特性应该始终由使用这款乐高的用户混合在一起

因此,这里是典型的过度聚合方式(需要实例):

vs方式:


可能的用例是什么?为什么我需要做这些戏剧性的事情?“我偶然发现了一个类似这样的代码”-这个怎么样。别担心,这里没有什么戏剧性的,因为代码非常简单——你只是说一个特征应该总是与另一个特征混合在一起——这只是额外的编译时检查。例如,当你做责任链时——你可能会混合9000多个特征,所以最好能够指定一个或多个强制处理程序,like
vala=带有Hanler和OtherHandlerList的新逻辑;trait OtherHandlerList将MandatoryHandler扩展为带有H2的H1
——这只是第一次想到它。@user3102968为答案添加了更多示例
trait B extends A {
  type X = XImpl1      
  trait XImpl1 extends XLike { this: X => }
  trait XImpl2 extends XLike { this: X => }
}

val b = new B {}; import b._

scala> class ZZ extends XImpl1
defined class ZZ

scala> class ZZ extends XImpl2
<console>:40: error: illegal inheritance;
 self-type ZZ does not conform to b.XImpl2's selftype b.XImpl2 with b.X
       class ZZ extends XImpl2
                        ^
scala> class ZZ extends XImpl1 with XImpl2 // XImpl2 still can be mixed but only if XImpl1 present in linearization
defined class ZZ
trait A {
   type X1 <: XLike
   type X2 <: XLike

   trait XLike { this: X1 with X2 => }
} 

trait B extends A {
    type X1 = XImpl1  
    type X2 = XImpl2

    trait XImpl1 extends XLike { this: X1 with X2 => }
    trait XImpl2 extends XLike { this: X1 with X2 => }
    trait XImpl3 extends XLike { this: X1 with X2 => }
}
 val a = new Logic with Hanler with Group0
 trait Group0 extends MandatoryHandler1 with Group1 with H2
 trait Group1 extends H3 with H4 with MandatoryHandler2
 trait Group2 extends H2 with H5
 abstract class B {
    val helper1: H1 //mandatory, exactly H1, not some H
    val helper2: H2 
 }

 class C extends B {
    val helper1 = new H1 //mandatory, exactly H1, not some H
    val helper2 = new H2 
 }
 class H1 extends H {...} 
 class H2 extends H {...}    
 trait B extends A {
   type helper1 = H1
   type helper2 = H2

   trait H1 extends H // no abstract members here just mix-in
   trait H2 extends H
 }

 trait C extends H1 with H2