简体   繁体   English

关于类型细化语法的困惑

[英]Confusion about type refinement syntax

On Type Level, i stumble upon the following:在类型级别,我偶然发现以下内容:

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)
    }
}

The line that intrigued me is type Aux[A, S0] = StSource[A] {type S = S0}引起我兴趣的行是type Aux[A, S0] = StSource[A] {type S = S0}

In paerticular {type S = S0} in StSource[A] {type S = S0}在paerticular {type S = S0}StSource[A] {type S = S0}

I do not really know how to read this, as in interpreting the construct involved here.我真的不知道如何阅读这个,就像解释这里涉及的构造一样。

What is StSource[A] {type S = S0} ???什么是StSource[A] {type S = S0} ??? is that a structural type (part of it looks like it)是一种结构类型(它的一部分看起来像)

When defining type like trait, or class, Is the body of a class part of the type constructor represented by the class itself?当定义像 trait 或 class 这样的类型时,类的主体是否是由类本身表示的类型构造函数的一部分? what happened to the method in it ?里面的方法怎么了?

Really confused.真的很迷茫。 Can someone deconstruct that please ?有人可以解构吗?

StSource[A] {type S = S0} is a refined type. StSource[A] {type S = S0}是一个精炼的类型。 {type S = S0} is a type refinement. {type S = S0}是一种类型细化。

From one side, StSource[A] {type S = S0} is a subtype of StSource[A] .从一方面来看, StSource[A] {type S = S0}StSource[A]的子类型。

From the other side, StSource[A] is also an existential type with respect to StSource[A] {type S = S0} , namely StSource[A] is StSource.Aux[A, _] (aka StSource.Aux[A, X] forSome {type X} ).另一方面, 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 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 {𝑅}.复合类型𝑇1 with ... with 𝑇𝑛{𝑅} 表示具有在组件类型 𝑇1,...,𝑇𝑛 和细化 {𝑅} 中给出的成员的对象。 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;如果声明或定义覆盖了组件类型 𝑇1,…,𝑇𝑛 中的一个声明或定义,则覆盖的通常规则适用; otherwise the declaration or definition is said to be “structural”.否则,声明或定义被称为“结构性的”。

See also examples how to use refined types:另请参阅如何使用精炼类型的示例:

https://typelevel.org/blog/2015/07/19/forget-refinement-aux.html https://typelevel.org/blog/2015/07/19/forget-refinement-aux.html

How can I have a method parameter with type dependent on an implicit parameter? 如何让方法参数的类型依赖于隐式参数?

When are dependent types needed in Shapeless? 什么时候需要 Shapeless 中的依赖类型?

Why is the Aux technique required for type-level computations? 为什么类型级计算需要 Aux 技术?

Understanding the Aux pattern in Scala Type System 理解 Scala 类型系统中的 Aux 模式

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?当定义像 trait 或 class 这样的类型时,类的主体是否是由类本身表示的类型构造函数的一部分? what happened to the method in it ?里面的方法怎么了?

You can replace你可以更换

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)
  }

aka又名

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)
  }

with

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)
  }

but there is no sense in that because the type remains the same但没有意义,因为类型保持不变

def test[A, S0] = {
  implicitly[(StSource[A] {
    type S = S0
    def init: S
    def emit(s: S): (A, S)
  }) =:= (StSource[A] {type S = S0})]
}

When you add type S = S0 to the type you provide additional information (that type S is specific) but when you add def init: S , def emit(s: S): (A, S) to the type you don't provide additional information (methods init , emit being there is clear from the definition of class StSource[A] ).当您将type S = S0添加到类型时,您提供了额外的信息(该类型S是特定的)但是当您添加def init: Sdef emit(s: S): (A, S)到您没有的类型提供额外的信息(方法init ,从类StSource[A]的定义中可以清楚地emit )。

Other situation would be if the class were defined as just其他情况是,如果该类被定义为只是

sealed abstract class StSource[A] {
  type S
}

or even甚至

sealed abstract class StSource[A]

Then然后

StSource[A] {
  type S = S0
  def init: S
  def emit(s: S): (A, S)
}

would be a type different from StSource[A] or StSource[A] {type S = S0} (a subtype of them).将是不同于StSource[A]StSource[A] {type S = S0} (它们的子类型)的类型。 It would be a structural type (existence of init , emit would be checked using runtime reflection).这将是一个结构类型( init存在,将使用运行时反射检查emit )。 Here这里

{
  type S = S0
  def init: S
  def emit(s: S): (A, S)
}

is a refinement but not type refinement.是细化但不是类型细化。

Unlike def s ( init , emit ) type members don't have runtime representation (unless you persist them, eg with TypeTag s) so using type refinement doesn't have runtime overhead.def s ( init , emit ) 类型成员不同,类型成员没有运行时表示(除非您将它们持久化,例如使用TypeTag s),因此使用类型细化不会有运行时开销。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM