对类型细化语法的困惑
Confusion about type refinement syntax
在类型级别,我偶然发现了以下内容:
sealed abstract class StSource[A] {
type S
def init: S // create the initial state
def emit(s: S): (A, S) // emit a value, and update state
}
object StSource {
type Aux[A, S0] = StSource[A] {type S = S0}
def apply[A, S0](i: S0)(f: S0 => (A, S0)): Aux[A, S0] =
new StSource[A] {
type S = S0
def init = i
def emit(s: S0) = f(s)
}
}
让我感兴趣的是type Aux[A, S0] = StSource[A] {type S = S0}
特别是 {type S = S0}
在 StSource[A] {type S = S0}
我真的不知道怎么读这个,就像解释这里涉及的结构一样。
什么是StSource[A] {type S = S0}
???是不是结构类型(部分看起来像)
当定义像 trait 或 class 这样的类型时,class 的主体是否由 class 本身表示的类型构造函数的一部分?其中的方法发生了什么?
真的很困惑。有人可以解构吗?
StSource[A] {type S = S0}
是精致型。 {type S = S0}
是一种类型优化。
一方面,StSource[A] {type S = S0}
是 StSource[A]
的子类型。
从另一方面来说,StSource[A]
也是相对于StSource[A] {type S = S0}
的存在类型,即StSource[A]
是StSource.Aux[A, _]
(又名StSource.Aux[A, X] forSome {type X}
)。
def test[A, S] = {
implicitly[StSource.Aux[A, S] <:< StSource[A]]
implicitly[StSource.Aux[A, _] =:= StSource[A]]
implicitly[StSource[A] =:= StSource.Aux[A, _]]
}
https://scala-lang.org/files/archive/spec/2.13/03-types.html#compound-types
A compound type 1 with … with {} represents objects with members as given in the component types 1,…, and the refinement {}. A refinement {} contains declarations and type definitions. If a declaration or definition overrides a declaration or definition in one of the component types 1,…,, the usual rules for overriding apply; otherwise the declaration or definition is said to be “structural”.
另请参阅如何使用优化类型的示例:
https://typelevel.org/blog/2015/07/19/forget-refinement-aux.html
Enforcing that dependent return type must implement typeclass
When defining type like trait, or class, Is the body of a class part of the type constructor represented by the class itself? what happened to the method in it ?
你可以替换
def apply[A, S0](i: S0)(f: S0 => (A, S0)): Aux[A, S0] =
new StSource[A] {
override type S = S0
override def init = i
override def emit(s: S0) = f(s)
}
又名
def apply[A, S0](i: S0)(f: S0 => (A, S0)): StSource[A] {type S = S0} =
new StSource[A] {
override type S = S0
override def init = i
override def emit(s: S0) = f(s)
}
与
def apply[A, S0](i: S0)(f: S0 => (A, S0)): StSource[A] {
type S = S0
def init: S
def emit(s: S): (A, S)
} =
new StSource[A] {
override type S = S0
override def init = i
override def emit(s: S0) = f(s)
}
但没有意义,因为类型保持不变
def test[A, S0] = {
implicitly[(StSource[A] {
type S = S0
def init: S
def emit(s: S): (A, S)
}) =:= (StSource[A] {type S = S0})]
}
当您向类型添加 type S = S0
时,您提供了额外信息(该类型 S
是特定的)但是当您向类型添加 def init: S
、def emit(s: S): (A, S)
时,您不提供额外信息(方法 init
、emit
从 class StSource[A]
的定义中可以清楚地看出)。
其他情况是 class 被定义为
sealed abstract class StSource[A] {
type S
}
甚至
sealed abstract class StSource[A]
然后
StSource[A] {
type S = S0
def init: S
def emit(s: S): (A, S)
}
将是不同于 StSource[A]
或 StSource[A] {type S = S0}
的类型(它们的子类型)。它将是一种结构类型(init
、emit
的存在将使用运行时反射进行检查)。这里
{
type S = S0
def init: S
def emit(s: S): (A, S)
}
是细化但不是类型细化。
不像 def
s (init
, emit
) 类型成员没有运行时表示(除非你坚持他们,例如 TypeTag
s)所以使用类型细化没有运行时开销。
在类型级别,我偶然发现了以下内容:
sealed abstract class StSource[A] {
type S
def init: S // create the initial state
def emit(s: S): (A, S) // emit a value, and update state
}
object StSource {
type Aux[A, S0] = StSource[A] {type S = S0}
def apply[A, S0](i: S0)(f: S0 => (A, S0)): Aux[A, S0] =
new StSource[A] {
type S = S0
def init = i
def emit(s: S0) = f(s)
}
}
让我感兴趣的是type Aux[A, S0] = StSource[A] {type S = S0}
特别是 {type S = S0}
在 StSource[A] {type S = S0}
我真的不知道怎么读这个,就像解释这里涉及的结构一样。
什么是StSource[A] {type S = S0}
???是不是结构类型(部分看起来像)
当定义像 trait 或 class 这样的类型时,class 的主体是否由 class 本身表示的类型构造函数的一部分?其中的方法发生了什么?
真的很困惑。有人可以解构吗?
StSource[A] {type S = S0}
是精致型。 {type S = S0}
是一种类型优化。
一方面,StSource[A] {type S = S0}
是 StSource[A]
的子类型。
从另一方面来说,StSource[A]
也是相对于StSource[A] {type S = S0}
的存在类型,即StSource[A]
是StSource.Aux[A, _]
(又名StSource.Aux[A, X] forSome {type X}
)。
def test[A, S] = {
implicitly[StSource.Aux[A, S] <:< StSource[A]]
implicitly[StSource.Aux[A, _] =:= StSource[A]]
implicitly[StSource[A] =:= StSource.Aux[A, _]]
}
https://scala-lang.org/files/archive/spec/2.13/03-types.html#compound-types
A compound type 1 with … with {} represents objects with members as given in the component types 1,…, and the refinement {}. A refinement {} contains declarations and type definitions. If a declaration or definition overrides a declaration or definition in one of the component types 1,…,, the usual rules for overriding apply; otherwise the declaration or definition is said to be “structural”.
另请参阅如何使用优化类型的示例:
https://typelevel.org/blog/2015/07/19/forget-refinement-aux.html
Enforcing that dependent return type must implement typeclass
When defining type like trait, or class, Is the body of a class part of the type constructor represented by the class itself? what happened to the method in it ?
你可以替换
def apply[A, S0](i: S0)(f: S0 => (A, S0)): Aux[A, S0] =
new StSource[A] {
override type S = S0
override def init = i
override def emit(s: S0) = f(s)
}
又名
def apply[A, S0](i: S0)(f: S0 => (A, S0)): StSource[A] {type S = S0} =
new StSource[A] {
override type S = S0
override def init = i
override def emit(s: S0) = f(s)
}
与
def apply[A, S0](i: S0)(f: S0 => (A, S0)): StSource[A] {
type S = S0
def init: S
def emit(s: S): (A, S)
} =
new StSource[A] {
override type S = S0
override def init = i
override def emit(s: S0) = f(s)
}
但没有意义,因为类型保持不变
def test[A, S0] = {
implicitly[(StSource[A] {
type S = S0
def init: S
def emit(s: S): (A, S)
}) =:= (StSource[A] {type S = S0})]
}
当您向类型添加 type S = S0
时,您提供了额外信息(该类型 S
是特定的)但是当您向类型添加 def init: S
、def emit(s: S): (A, S)
时,您不提供额外信息(方法 init
、emit
从 class StSource[A]
的定义中可以清楚地看出)。
其他情况是 class 被定义为
sealed abstract class StSource[A] {
type S
}
甚至
sealed abstract class StSource[A]
然后
StSource[A] {
type S = S0
def init: S
def emit(s: S): (A, S)
}
将是不同于 StSource[A]
或 StSource[A] {type S = S0}
的类型(它们的子类型)。它将是一种结构类型(init
、emit
的存在将使用运行时反射进行检查)。这里
{
type S = S0
def init: S
def emit(s: S): (A, S)
}
是细化但不是类型细化。
不像 def
s (init
, emit
) 类型成员没有运行时表示(除非你坚持他们,例如 TypeTag
s)所以使用类型细化没有运行时开销。