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/taste-modeling.md
+84-18Lines changed: 84 additions & 18 deletions
Original file line number
Diff line number
Diff line change
@@ -229,25 +229,59 @@ I didn’t include that because I didn’t know if enums are intended
229
229
to replace the Scala2 “sealed trait + case class” pattern. How to resolve?
230
230
{% endcomment %}
231
231
232
-
When writing code in an FP style, you’ll use these constructs:
232
+
When writing code in an FP style, you’ll use these concepts:
233
233
234
-
- Enums to define ADTs
235
-
- Case classes
236
-
- Traits
234
+
- Algebraic Data Types to define the data
235
+
- Traits for functionality on the data.
237
236
238
-
### Enums
237
+
### Enumerations and Sum Types
238
+
239
+
Sum types are one way to model algebraic data types (ADTs) in Scala.
240
+
241
+
They are used when data can be represented with different choices.
239
242
240
-
The `enum` construct is a great way to model algebraic data types (ADTs) in Scala 3.
241
243
For instance, a pizza has three main attributes:
242
244
243
245
- Crust size
244
246
- Crust type
245
247
- Toppings
246
248
247
-
These are concisely modeled with enums:
249
+
These are concisely modeled with enumerations, which are sum types that only contain singleton values:
250
+
251
+
{% tabs enum_1 class=tabs-scala-version %}
252
+
{% tab 'Scala 2' for=enum_1 %}
253
+
254
+
In Scala 2 `sealed` classes and `case object` are combined to define an enumeration:
255
+
256
+
```scala
257
+
sealedabstractclassCrustSize
258
+
objectCrustSize {
259
+
caseobjectSmallextendsCrustSize
260
+
caseobjectMediumextendsCrustSize
261
+
caseobjectLargeextendsCrustSize
262
+
}
263
+
264
+
sealedabstractclassCrustType
265
+
objectCrustType {
266
+
caseobjectThinextendsCrustType
267
+
caseobjectThickextendsCrustType
268
+
caseobjectRegularextendsCrustType
269
+
}
270
+
271
+
sealedabstractclassTopping
272
+
objectTopping {
273
+
caseobjectCheeseextendsTopping
274
+
caseobjectPepperoniextendsTopping
275
+
caseobjectBlackOlivesextendsTopping
276
+
caseobjectGreenOlivesextendsTopping
277
+
caseobjectOnionsextendsTopping
278
+
}
279
+
```
280
+
281
+
{% endtab %}
282
+
{% tab 'Scala 3' for=enum_1 %}
248
283
249
-
{% tabs enum_1 %}
250
-
{% tab 'Scala 3 Only' for=enum_1 %}
284
+
Scala 3 offers the `enum` construct for defining enumerations:
251
285
252
286
```scala
253
287
enumCrustSize:
@@ -263,10 +297,28 @@ enum Topping:
263
297
{% endtab %}
264
298
{% endtabs %}
265
299
266
-
Once you have an enum you can use it in all of the ways you normally use a trait, class, or object:
300
+
Once you have an enumeration you can import its members as ordinary values:
301
+
302
+
{% tabs enum_2 class=tabs-scala-version %}
303
+
{% tab 'Scala 2' for=enum_2 %}
304
+
305
+
```scala
306
+
importCrustSize._
307
+
valcurrentCrustSize=Small
308
+
309
+
// enums in a `match` expression
310
+
currentCrustSize match {
311
+
caseSmall=> println("Small crust size")
312
+
caseMedium=> println("Medium crust size")
313
+
caseLarge=> println("Large crust size")
314
+
}
315
+
316
+
// enums in an `if` statement
317
+
if (currentCrustSize ==Small) println("Small crust size")
318
+
```
267
319
268
-
{% tabs enum_2 %}
269
-
{% tab 'Scala 3 Only' for=enum_2 %}
320
+
{% endtab %}
321
+
{% tab 'Scala 3' for=enum_2 %}
270
322
271
323
```scala
272
324
importCrustSize.*
@@ -285,25 +337,39 @@ if currentCrustSize == Small then println("Small crust size")
285
337
{% endtab %}
286
338
{% endtabs %}
287
339
288
-
Here’s another example of how to create and use an ADT with Scala:
340
+
Here’s another example of how to create a sum type with Scala, this would not be called an enumeration because the `Succ` case has parameters:
289
341
290
-
{% tabs enum_3 %}
291
-
{% tab 'Scala 3 Only' for=enum_3 %}
342
+
{% tabs enum_3 class=tabs-scala-version %}
343
+
{% tab 'Scala 2' for=enum_3 %}
344
+
345
+
```scala
346
+
sealedabstractclassNat
347
+
objectNat {
348
+
caseobjectZeroextendsNat
349
+
caseclassSucc(pred: Nat) extendsNat
350
+
}
351
+
```
352
+
353
+
Sum Types are covered in detail in the [Domain Modeling]({% link _overviews/scala3-book/domain-modeling-tools.md %}) section of this book.
354
+
355
+
{% endtab %}
356
+
{% tab 'Scala 3' for=enum_3 %}
292
357
293
358
```scala
294
359
enumNat:
295
360
caseZero
296
361
caseSucc(pred: Nat)
297
362
```
298
363
364
+
Enums are covered in detail in the [Domain Modeling]({% link _overviews/scala3-book/domain-modeling-tools.md %}) section of this book, and in the [Reference documentation]({{ site.scala3ref }}/enums/enums.html).
365
+
299
366
{% endtab %}
300
367
{% endtabs %}
301
368
302
-
Enums are covered in detail in the [Domain Modeling][data-1] section of this book, and in the [Reference documentation]({{ site.scala3ref }}/enums/enums.html).
369
+
### Product Types
303
370
304
-
### Case classes
371
+
A product type is an algebraic data type (ADT) that only has one shape, for example a singleton object, represented in Scala by a `case` object; or an immutable structure with accessible fields, represented by a `case` class.
305
372
306
-
The Scala `case` class lets you model concepts with immutable data structures.
307
373
A `case` class has all of the functionality of a `class`, and also has additional features baked in that make them useful for functional programming.
308
374
When the compiler sees the `case` keyword in front of a `class` it has these effects and benefits:
0 commit comments