Skip to content

Commit

Permalink
Fixup markup in union-types
Browse files Browse the repository at this point in the history
  • Loading branch information
felixmulder committed May 26, 2017
1 parent 8d750a1 commit 8013ea4
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 46 deletions.
107 changes: 63 additions & 44 deletions docs/docs/reference/desugarEnums.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,106 +41,125 @@ comma separated simple cases into a sequence of cases.

2. An enum class definition

enum class E ... extends <parents> ...
enum class E ... extends <parents> ...

expands to a `sealed` `abstract` class that extends the `scala.Enum` trait:

sealed abstract class E ... extends <parents> with scala.Enum ...

3. If `E` is an enum class without type parameters, then a case in its companion object without an extends clause

case C <params> <body>
case C <params> <body>

expands to

case C <params> <body> extends E
case C <params> <body> extends E

4. If `E` is an enum class with type parameters `Ts`, then a case in its companion object without an extends clause
4. If `E` is an enum class with type parameters `Ts`, then a case in its
companion object without an extends clause

case C <params> <body>
case C <params> <body>

expands according to two alternatives, depending whether `C` has type parameters or not. If `C` has type parameters, they must have the same names and appear in the same order as the enum type parameters `Ts` (variances may be different, however). In this case
expands according to two alternatives, depending whether `C` has type
parameters or not. If `C` has type parameters, they must have the same
names and appear in the same order as the enum type parameters `Ts`
(variances may be different, however). In this case

case C [Ts] <params> <body>
case C [Ts] <params> <body>

expands to
expands to

case C[Ts] <params> extends E[Ts] <body>
case C[Ts] <params> extends E[Ts] <body>

For the case where `C` does not have type parameters, assume `E`'s type parameters are
For the case where `C` does not have type parameters, assume `E`'s type
parameters are

V1 T1 > L1 <: U1 , ... , Vn Tn >: Ln <: Un (n > 0)
V1 T1 > L1 <: U1 , ... , Vn Tn >: Ln <: Un (n > 0)

where each of the variances `Vi` is either `'+'` or `'-'`. Then the case expands to
where each of the variances `Vi` is either `'+'` or `'-'`. Then the case
expands to

case C <params> extends E[B1, ..., Bn] <body>
case C <params> extends E[B1, ..., Bn] <body>

where `Bi` is `Li` if `Vi = '+'` and `Ui` if `Vi = '-'`. It is an error if `Bi` refers to some other type parameter `Tj (j = 0,..,n-1)`. It is also an error if `E` has type parameters that are non-variant.
where `Bi` is `Li` if `Vi = '+'` and `Ui` if `Vi = '-'`. It is an error if
`Bi` refers to some other type parameter `Tj (j = 0,..,n-1)`. It is also
an error if `E` has type parameters that are non-variant.

5. A class case

case C <params> ...
case C <params> ...

expands analogous to a case class:
expands analogous to a case class:

final case class C <params> ...
final case class C <params> ...

However, unlike for a regular case class, the return type of the associated `apply` method is a fully parameterized type instance of the enum class `E` itself instead of `C`. Also the enum case defines an `enumTag` method of the form
However, unlike for a regular case class, the return type of the associated
`apply` method is a fully parameterized type instance of the enum class `E`
itself instead of `C`. Also the enum case defines an `enumTag` method of
the form

def enumTag = n
def enumTag = n

where `n` is the ordinal number of the case in the companion object, starting from 0.
where `n` is the ordinal number of the case in the companion object,
starting from 0.

6. A value case

case C extends <parents> <body>
case C extends <parents> <body>

expands to a value definition
expands to a value definition

val C = new <parents> { <body>; def enumTag = n; $values.register(this) }
val C = new <parents> { <body>; def enumTag = n; $values.register(this) }

where `n` is the ordinal number of the case in the companion object, starting from 0.
The statement `$values.register(this)` registers the value as one of the `enumValues` of the
enumeration (see below). `$values` is a compiler-defined private value in
the companion object.
where `n` is the ordinal number of the case in the companion object,
starting from 0. The statement `$values.register(this)` registers the value
as one of the `enumValues` of the enumeration (see below). `$values` is a
compiler-defined private value in the companion object.

7. A simple case

case C
case C

of an enum class `E` that does not take type parameters expands to
of an enum class `E` that does not take type parameters expands to

val C = $new(n, "C")
val C = $new(n, "C")

Here, `$new` is a private method that creates an instance of of `E` (see below).
Here, `$new` is a private method that creates an instance of of `E` (see
below).

8. A simple case consisting of a comma-separated list of enum names

case C_1, ..., C_n

expands to
expands to

case C_1; ...; case C_n
case C_1; ...; case C_n

Any modifiers or annotations on the original case extend to all expanded cases.
Any modifiers or annotations on the original case extend to all expanded
cases.

## Translation of Enumerations

Non-generic enum classes `E` that define one or more singleton cases
are called _enumerations_. Companion objects of enumerations define
the following additional members.

- A method `enumValue` of type `scala.collection.immutable.Map[Int, E]`. `enumValue(n)` returns the singleton case value with ordinal number `n`.
- A method `enumValueNamed` of type `scala.collection.immutable.Map[String, E]`. `enumValueNamed(s)` returns the singleton case value whose `toString` representation is `s`.
- A method `enumValues` which returns an `Iterable[E]` of all singleton case values in `E`, in the order of their definitions.
- A method `enumValue` of type `scala.collection.immutable.Map[Int, E]`.
`enumValue(n)` returns the singleton case value with ordinal number `n`.
- A method `enumValueNamed` of type `scala.collection.immutable.Map[String, E]`.
`enumValueNamed(s)` returns the singleton case value whose `toString`
representation is `s`.
- A method `enumValues` which returns an `Iterable[E]` of all singleton case
values in `E`, in the order of their definitions.

Companion objects that contain at least one simple case define in addition:

- A private method `$new` which defines a new simple case value with given ordinal number and name. This method can be thought as being defined as follows.

def $new(tag: Int, name: String): ET = new E {
def enumTag = tag
def toString = name
$values.register(this) // register enum value so that `valueOf` and `values` can return it.
}
- A private method `$new` which defines a new simple case value with given
ordinal number and name. This method can be thought as being defined as
follows.

def $new(tag: Int, name: String): ET = new E {
def enumTag = tag
def toString = name
$values.register(this) // register enum value so that `valueOf` and `values` can return it.
}
4 changes: 2 additions & 2 deletions docs/docs/reference/union-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ val either: Password | UserName = UserName(Eve)
```

The type of `res2` is `Object | Product`, which is a supertype of
`UserName` and `Product, but not the least supertype `Password |
`UserName` and `Product`, but not the least supertype `Password |
UserName`. If we want the least supertype, we have to give it
explicitely, as is done for the type of `Either`. More precisely, the
typechecker will _widen_ a union type to a non-union type when
inferring the type of ` `val` or `var`, or the result type of a `def`,
inferring the type of `val` or `var`, or the result type of a `def`,
or the argument to pass for a type parameter. The widened type of `A
| B` is usually the intersection of all class or trait types that are
supertypes of both `A` and `B`; it does not include any refinements.
Expand Down

0 comments on commit 8013ea4

Please sign in to comment.