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: _overviews/scala3-book/ca-context-bounds.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,7 @@ next-page: ca-given-imports
13
13
- TODO: define "synthesized" and "synthesized arguments"
14
14
{% endcomment %}
15
15
16
-
In many situations the name of a _context parameter_ doesn’t have to be mentioned explicitly, since it’s only used in synthesized arguments for other context parameters.
16
+
In many situations the name of a _context parameter_ doesn’t have to be mentioned explicitly, since it’s only used by the compiler in synthesized arguments for other context parameters.
17
17
In that case you don’t have to define a parameter name, and can just provide the parameter type.
In our call to `renderWidget(List("cart"))` the Scala compiler will see that there is a term of type `Config` in scope (the `c`) and automatically provide it to `renderWidget`.
48
48
So the program is equivalent to the one above.
49
49
50
-
In fact, since we do not need to refer to `c` in our implementation of `renderWebsite` anymore, we can even omit it in the signature:
50
+
In fact, since we do not need to refer to `c` in our implementation of `renderWebsite` anymore, we can even omit its name in the signature:
In the last example, when an anonymous function consists of one statement that takes a single argument, you don’t have to name the argument, so even `-` isn’t required.
106
+
In the last example, when an anonymous function consists of one function call that takes a single argument, you don’t have to name the argument, so even `_` isn’t required.
107
107
108
108
Finally, you can combine HOFs as desired to solve problems:
109
109
@@ -217,19 +217,19 @@ david
217
217
## `head`
218
218
219
219
The `head` method comes from Lisp and other earlier functional programming languages.
220
-
It’s used to print the first element (the head element) of a list:
220
+
It’s used to access the first element (the head element) of a list:
221
221
222
222
```scala
223
-
oneToTen.head //Int = 1
223
+
oneToTen.head // 1
224
224
names.head // adam
225
225
```
226
226
227
227
Because a `String` can be seen as a sequence of characters, you can also treat it like a list.
228
228
This is how `head` works on these strings:
229
229
230
230
```scala
231
-
"foo".head //Char = 'f'
232
-
"bar".head //Char = 'b'
231
+
"foo".head // 'f'
232
+
"bar".head // 'b'
233
233
```
234
234
235
235
`head` is a great method to work with, but as a word of caution it can also throw an exception when called on an empty collection:
@@ -242,7 +242,7 @@ emptyList.head // java.util.NoSuchElementException: head of empty
242
242
Because of this you may want to use `headOption` instead of `head`, especially when programming in a functional style:
243
243
244
244
```scala
245
-
emptyList.headOption //Option[Int] = None
245
+
emptyList.headOption // None
246
246
```
247
247
248
248
As shown, it doesn’t throw an exception, it simply returns the type `Option` that has the value `None`.
@@ -256,7 +256,7 @@ The `tail` method also comes from Lisp, and it’s used to print every element i
Copy file name to clipboardExpand all lines: _overviews/scala3-book/fp-functional-error-handling.md
+10-8
Original file line number
Diff line number
Diff line change
@@ -106,7 +106,7 @@ makeInt(x) match
106
106
caseNone=> println("That didn’t work.")
107
107
```
108
108
109
-
In this example, if `x` can be converted to an `Int`, the first `case`statement is executed; if `x` can’t be converted to an `Int`, the second `case`statement is executed.
109
+
In this example, if `x` can be converted to an `Int`, the expression on the right-hand side of the first `case`clause is evaluated; if `x` can’t be converted to an `Int`, the expression on the right-hand side of the second `case`clause is evaluated.
110
110
111
111
112
112
@@ -240,19 +240,20 @@ makeInt(x) match
240
240
Getting back to `null` values, a place where a `null` value can silently creep into your code is with a classlikethis:
241
241
242
242
```scala
243
-
classAddress:
243
+
classAddress(
244
244
varstreet1:String,
245
245
varstreet2:String,
246
-
varcity:String,
247
-
varstate:String,
246
+
varcity:String,
247
+
varstate:String,
248
248
varzip:String
249
+
)
249
250
```
250
251
251
252
While every address on Earth has a `street1` value, the `street2` value is optional.
252
253
As a result, the `street2` field can be assigned a `null` value:
253
254
254
255
```scala
255
-
valsanta=newAddress(
256
+
valsanta=Address(
256
257
"1 Main Street",
257
258
null, // <-- D’oh! A null value!
258
259
"North Pole",
@@ -265,18 +266,19 @@ Historically, developers have used blank strings and null values in this situati
265
266
InScala---and other modern languages---the correct solution is to declare up front that `street2` is optional:
266
267
267
268
```scala
268
-
classAddress:
269
+
classAddress(
269
270
varstreet1:String,
270
271
varstreet2:Option[String], // an optional value
271
272
varcity:String,
272
273
varstate:String,
273
274
varzip:String
275
+
)
274
276
```
275
277
276
278
Now developers can write more accurate code like this:
Copy file name to clipboardExpand all lines: _overviews/scala3-book/types-type-classes.md
+2-2
Original file line number
Diff line number
Diff line change
@@ -23,7 +23,7 @@ In Scala 3, _type classes_ are just _traits_ with one or more type parameters, l
23
23
trait Show[A]:
24
24
def show(a: A): String
25
25
```
26
-
Instances of `Show` for a particular type `A` witness that `A`we can show an instance of type `A`.
26
+
Instances of `Show` for a particular type `A` witness that we can show (i.e., produce a text representation of) an instance of type `A`.
27
27
For example, let’s look at the following `Show` instance for `Int` values:
28
28
29
29
```scala
@@ -43,7 +43,7 @@ toHtml(42)(ShowInt())
43
43
// results in "<p>The number is 42!</p>"
44
44
```
45
45
46
-
#### Automatically passing Type Class Instances
46
+
#### Automatically passing type class instances
47
47
Since type classes are a very important way to structure software, Scala 3 offers additional features that make working with them very convenient.
48
48
We discuss these additional features (which fall into the category of *Contextual Abstractions*) in a [later chapter][typeclasses-chapter] of this book.
Copy file name to clipboardExpand all lines: _overviews/scala3-book/types-variance.md
+8-8
Original file line number
Diff line number
Diff line change
@@ -22,11 +22,11 @@ Let us also assume the following parameterized types:
22
22
traitPipeline[T]:
23
23
defprocess(t: T):T
24
24
25
-
// an example of an covariant type
25
+
// an example of a covariant type
26
26
traitProducer[+T]:
27
27
defmake:T
28
28
29
-
// an example of an contravariant type
29
+
// an example of a contravariant type
30
30
traitConsumer[-T]:
31
31
deftake(t: T):Unit
32
32
```
@@ -73,7 +73,7 @@ In contrast to `Pipeline`, which is invariant, the type `Producer` is marked as
73
73
This is valid, since the type parameter is only used in a _return position_.
74
74
75
75
Marking it as covariant means that we can pass (or return) a `Producer[Book]` where a `Producer[Buyable]` is expected.
76
-
And in fact, this is sound: The type of `Producer[Buyable].make` only promises to _return_ a `Buyable`.
76
+
And in fact, this is sound. The type of `Producer[Buyable].make` only promises to _return_ a `Buyable`.
77
77
As a caller of `make`, we will be happy to also accept a `Book`, which is a subtype of `Buyable`---that is, it is _at least_ a `Buyable`.
78
78
79
79
This is illustrated by the following example, where the function `makeTwo` expects a `Producer[Buyable]`:
@@ -108,12 +108,12 @@ They have an additional ISBN method in our example, but you are free to ignore t
108
108
In contrast to the type `Producer`, which is marked as covariant, the type `Consumer` is marked as **contravariant** by prefixing the type parameter with a `-`.
109
109
This is valid, since the type parameter is only used in an _argument position_.
110
110
111
-
Marking it as contravariant means that we can pass (or return) a `Producer[Item]` where a `Producer[Buyable]` is expected.
112
-
That is, we have the subtyping relationship `Producer[Item] <: Producer[Buyable]`.
113
-
Remember, for type `Consumer`, it was the other way around, and we had `Consumer[Buyable] <: Consumer[Item]`.
111
+
Marking it as contravariant means that we can pass (or return) a `Consumer[Item]` where a `Consumer[Buyable]` is expected.
112
+
That is, we have the subtyping relationship `Consumer[Item] <: Consumer[Buyable]`.
113
+
Remember, for type `Producer`, it was the other way around, and we had `Producer[Buyable] <: Producer[Item]`.
114
114
115
-
And in fact, this is sound: The type of `Producer[Buyable].make` only promises us to _return_ a `Buyable`.
116
-
As a caller of `make`, we will be happy to also accept a `Book`, which is a subtype of `Buyable`---that is, it is _at least_a `Buyable`.
115
+
And in fact, this is sound. The method `Consumer[Item].take` accepts an `Item`.
116
+
As a caller of `take`, we can also supply a `Buyable`, which will be happily accepted by the `Consumer[Item]` since `Buyable`is a subtype of `Item`---that is, it is _at least_an `Item`.
0 commit comments