You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/_docs/reference/experimental/into-modifier.md
+53-14
Original file line number
Diff line number
Diff line change
@@ -32,10 +32,10 @@ The `into` modifier on the type of `elems` means that implicit conversions can b
32
32
`into` also allows conversions on the results of function arguments. For instance, consider the new proposed signature of the `flatMap` method on `List[A]`:
33
33
34
34
```scala
35
-
defflatMap[B](f: into A=>IterableOnce[B]):List[B]
35
+
defflatMap[B](f: A=> intoIterableOnce[B]):List[B]
36
36
```
37
-
This allows a conversion of the actual argument to the function type `A => IterableOnce[B]`. Crucially, it also allows that conversion to be applied to
38
-
the function result. So the following would work:
37
+
This accepts all actual arguments `f` that, when applied to an `A`, give a result
38
+
that is convertible to `IterableOnce[B]`. So the following would work:
39
39
```scala
40
40
scala>valxs=List(1, 2, 3)
41
41
scala> xs.flatMap(x => x.toString * x)
@@ -49,7 +49,7 @@ When applied to a vararg parameter, `into` allows a conversion on each argument
49
49
number of `IterableOnce[Char]` arguments, and also allows implicit conversions into `IterableOnce[Char]`:
50
50
51
51
```scala
52
-
defconcatAll(xss: into IterableOnce[Char]*):List[Char] =
would apply two _different_ implicit conversions: the conversion from `String` to `Iterable[Char]` gets applied to the second argument and the conversion from `Array[Char]` to `Iterable[Char]` gets applied to the third argument.
60
60
61
+
Note that a vararg parameter type with into modifiers needs to be put in parentheses, as is shown in the example above. This is to make the precedence clear: each element of the argument sequence is converted by itself.
62
+
61
63
## Retrofitting Scala 2 libraries
62
64
63
-
A new annotation `allowConversions` has the same effect as an `into` modifier. It is defined as an `@experimental` class in package `scala.annotation`. It is intended to be used for retrofitting Scala 2 library code so that Scala 3 conversions can be applied to arguments without language imports. For instance, the definitions of
65
+
There is also an annotation `@into` in the `scala.annotation` package that has
66
+
has the same effect as an `into` modifier. It is intended to be used for retrofitting Scala 2 library code so that Scala 3 conversions can be applied to arguments without language imports. For instance, the definitions of
64
67
`++` and `flatMap` in the Scala 2.13 `List` class could be retrofitted as follows.
For Scala 3 code, the `into` modifier is preferred, because it adheres to the principle that annotations should not influence typing and type inference in Scala.
73
+
74
+
## Restrictions
75
+
76
+
The `into` modifier is only allowed in the types method parameters. It can be given either for the whole type, or some result type of a top-level function type, but not anywhere else. The `into` modifier does not propagate outside the method. In particular, a partially applied method does not propagate `into` modifiers to its result.
77
+
78
+
**Example:**
79
+
80
+
Say we have
81
+
```scala
82
+
deff(x: Int)(y: into Text):Unit
83
+
```
84
+
then
85
+
```scala
86
+
f(3) :Text=>Unit
87
+
```
88
+
Note the `into` modifier is not longer present on the type of `f(3)`. Therefore, follow-on arguments to `f(3)` do not allow implicit conversions. Generally it is not possible to
89
+
define function types that allow implicit conversions on their arguments, but it is possible to define SAM types that allow conversions. E.g.
90
+
```scala
91
+
traitConvArg:
92
+
defapply(x: into Text):Unit
93
+
94
+
valx:ConvArg= f(3)(_)
95
+
```
96
+
97
+
Note this is similar to the way vararg parameters are handled in Scala. If we have
98
+
```scala
99
+
defg(x: Int)(y: Int*):Unit
100
+
```
101
+
then
102
+
```scala
103
+
g(4) :Seq[Int] =>Unit
68
104
```
69
-
For Scala 3 code, the `into` modifier is preferred. First, because it is shorter,
70
-
and second, because it adheres to the principle that annotations should not influence
71
-
typing and type inference in Scala.
105
+
Observe that the vararg annotation also got dropped in the result type of `g(4)`.
72
106
73
107
## Syntax changes
74
108
75
109
The addition to the grammar is:
76
110
```
77
-
ParamType ::= [‘=>’] ParamValueType
78
-
ParamValueType ::= [‘into‘] ExactParamType
79
-
ExactParamType ::= Type [‘*’]
111
+
ParamType ::= [‘=>’] ParamValueType
112
+
ParamValueType ::= Type [‘*’]
113
+
| IntoType
114
+
| ‘(’ IntoType ‘)’ ‘*’
115
+
IntoType ::= [‘into’] IntoTargetType
116
+
| ‘(’ IntoType ‘)’
117
+
IntoTargetType ::= Type
118
+
| FunTypeArgs (‘=>’ | ‘?=>’) IntoType
80
119
```
81
-
As the grammar shows, `into` can only applied to the type of a parameter; it is illegal in other positions.
120
+
As the grammar shows, `into` can only applied to the type of a parameter; it is illegal in other positions. Also, `into` modifiers in vararg types have to be enclosed in parentheses.
0 commit comments