Skip to content

Commit 219bc3c

Browse files
author
aesteve
committed
Use new type wildcard syntax
1 parent 466bff9 commit 219bc3c

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

docs/docs/reference/contextual/typeclasses.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,16 @@ assert(3 == List(1, 2).combineAll)
8585

8686
A `Functor` for a type provides the ability for its values to be "mapped over", i.e. apply a function that transforms inside a value while remembering its shape. For example, to modify every element of a collection without dropping or adding elements.
8787
We can represent all types that can be "mapped over" with `F`. It's a type constructor: the type of its values becomes concrete when provided a type argument.
88-
Therefore we write it `F[_]`, hinting that it is a type with internal details we can inspect.
88+
Therefore we write it `F[?]`, hinting that it is a type with internal details we can inspect.
8989
The definition of a generic `Functor` would thus be written as:
9090

9191
```scala
92-
trait Functor[F[_]] {
92+
trait Functor[F[?]] {
9393
def map[A, B](original: F[A], mapper: A => B): F[B]
9494
}
9595
```
9696

97-
Which could read as follows: "A `Functor` for the type constructor `F[_]` represents the ability to transform `F[A]` to `F[B]` through the application of the `mapper` function whose type is `A => B`". We call the `Functor` definition here a _typeclass_.
97+
Which could read as follows: "A `Functor` for the type constructor `F[?]` represents the ability to transform `F[A]` to `F[B]` through the application of the `mapper` function whose type is `A => B`". We call the `Functor` definition here a _typeclass_.
9898
This way, we could define an instance of `Functor` for the `List` type:
9999

100100
```scala
@@ -108,7 +108,7 @@ With this `given` instance in scope, everywhere a `Functor` is expected, the com
108108

109109
For instance, we may write such a testing method:
110110
```scala
111-
def assertTransformation[F[_]: Functor, A, B](expected: F[B], original: F[A], mapping: A => B): Unit =
111+
def assertTransformation[F[?]: Functor, A, B](expected: F[B], original: F[A], mapping: A => B): Unit =
112112
assert(expected == summon[Functor[F]].map(original, mapping))
113113
```
114114

@@ -122,7 +122,7 @@ That's a first step, but in practice we probably would like the `map` function t
122122
As in the previous example of Monoids, [`extension` methods](extension-methods-new.html) help achieving that. Let's re-define the `Functor` _typeclass_ with extension methods.
123123

124124
```scala
125-
trait Functor[F[_]] {
125+
trait Functor[F[?]] {
126126
def [A, B](original: F[A]).map(mapper: A => B): F[B]
127127
}
128128
```
@@ -139,7 +139,7 @@ given Functor[List] {
139139
It simplifies the `assertTransformation` method:
140140

141141
```scala
142-
def assertTransformation[F[_]: Functor, A, B](expected: F[B], original: F[A], mapping: A => B): Unit =
142+
def assertTransformation[F[?]: Functor, A, B](expected: F[B], original: F[A], mapping: A => B): Unit =
143143
assert(expected == original.map(mapping))
144144
```
145145

@@ -156,14 +156,14 @@ Now, applying the `List.map` ability with the following mapping function as para
156156

157157
To avoid avoid managing lists of lists, we may want to "flatten" the values in a single list.
158158

159-
That's where `Monad` enters the party. A `Monad` for type `F[_]` is a `Functor[F]` with 2 more abilities:
159+
That's where `Monad` enters the party. A `Monad` for type `F[?]` is a `Functor[F]` with 2 more abilities:
160160
* the flatten ability we just described: turning `F[A]` to `F[B]` when given a `mapping: A => F[B]` function
161161
* the ability to create `F[A]` from a single value `A`
162162

163163
Here is the translation of this definition in Scala 3:
164164

165165
```scala
166-
trait Monad[F[_]] extends Functor[F] { // "A `Monad` for type `F[_]` is a `Functor[F]`" => thus has the `map` ability
166+
trait Monad[F[?]] extends Functor[F] { // "A `Monad` for type `F[?]` is a `Functor[F]`" => thus has the `map` ability
167167
def pure[A](x: A): F[A] // `pure` can construct F[A] from a single value A
168168
def [A, B](x: F[A]).flatMap(f: A => F[B]): F[B] // the flattening ability is named `flatMap`, using extension methods as previous examples
169169
def [A, B](x: F[A]).map(f: A => B) = x.flatMap(f `andThen` pure) // the `map(f)` ability is simply a combination of applying `f` then turning the result into an `F[A]` then applying `flatMap` to it

0 commit comments

Comments
 (0)