@@ -3,12 +3,13 @@ layout: doc-page
3
3
title : " Implementing Typeclasses"
4
4
---
5
5
6
- Given instances, extension methods and context bounds
7
- allow a concise and natural expression of _ typeclasses_ . Typeclasses are just traits
8
- with canonical implementations defined by given instances. Here are some examples of standard typeclasses:
6
+ In Scala 3, _ typeclasses_ are just traits whose implementation are defined by given instances.
7
+ Here are some examples of standard typeclasses:
9
8
10
9
### Semigroups and monoids:
11
10
11
+ Here's the ` Monoid ` typeclass definition:
12
+
12
13
``` scala
13
14
trait SemiGroup [T ] {
14
15
@ infix def (x : T ) combine (y : T ): T
@@ -17,25 +18,65 @@ trait SemiGroup[T] {
17
18
trait Monoid [T ] extends SemiGroup [T ] {
18
19
def unit : T
19
20
}
21
+ ```
20
22
21
- object Monoid {
22
- def apply [T ] with (m : Monoid [T ]) = m
23
- }
23
+ An implementation of this ` Monoid ` typeclass for the type ` String ` can be the following:
24
24
25
+ ``` scala
25
26
given as Monoid [String ] {
26
27
def (x : String ) combine (y : String ): String = x.concat(y)
27
28
def unit : String = " "
28
29
}
30
+ ```
29
31
32
+ Whereas for the type ` Int ` one could write the following:
33
+ ``` scala
30
34
given as Monoid [Int ] {
31
35
def (x : Int ) combine (y : Int ): Int = x + y
32
36
def unit : Int = 0
33
37
}
38
+ ```
34
39
35
- def sum [T : Monoid ](xs : List [T ]): T =
40
+ This monoid can now be used as _ context bound_ in the following ` combineAll ` method:
41
+
42
+ ``` scala
43
+ def combineAll [T : Monoid ](xs : List [T ]): T =
44
+ xs.foldLeft(summon[Monoid [T ]].unit)(_ combine _)
45
+ ```
46
+
47
+ To get rid of the ` summon[...] ` we can define a ` Monoid ` object as follows:
48
+
49
+ ``` scala
50
+ object Monoid {
51
+ def apply [T ] with (m : Monoid [T ]) = m
52
+ }
53
+ ```
54
+
55
+ Which would allow to re-write the ` combineAll ` method this way:
56
+
57
+ ``` scala
58
+ def combineAll [T : Monoid ](xs : List [T ]): T =
36
59
xs.foldLeft(Monoid [T ].unit)(_ combine _)
37
60
```
38
61
62
+ We can also benefit from [ extension methods] ( extension-methods-new.html ) to make this ` combineAll ` function accessible as a method on the ` List ` type:
63
+
64
+
65
+ ``` scala
66
+ def [T : Monoid ](xs : List [T ]).combineAll: T =
67
+ xs.foldLeft(Monoid [T ].unit)(_ combine _)
68
+ ```
69
+
70
+ Which allows one to write:
71
+
72
+ ``` scala
73
+ assert(" ab" == List (" a" , " b" ).combineAll)
74
+ ```
75
+ or:
76
+ ``` scala
77
+ assert(3 == List (1 , 2 ).combineAll)
78
+ ```
79
+
39
80
### Functors and monads:
40
81
41
82
``` scala
@@ -64,3 +105,6 @@ given readerMonad[Ctx] as Monad[[X] =>> Ctx => X] {
64
105
ctx => x
65
106
}
66
107
```
108
+
109
+
110
+ The conjunction of given instances, extension methods and context bounds allow a concise and natural expression of _ typeclasses_
0 commit comments