Skip to content

Add code tabs in scala3/book/fun-write-map-function #2625

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 3, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 51 additions & 3 deletions _overviews/scala3-book/fun-write-map-function.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,68 +20,116 @@ Focusing only on a `List[Int]`, you state:
Given that statement, you start to write the method signature.
First, you know that you want to accept a function as a parameter, and that function should transform an `Int` into some generic type `A`, so you write:

{% tabs map-accept-func-definition %}
{% tab 'Scala 2 and 3' %}
```scala
def map(f: (Int) => A)
```
{% endtab %}
{% endtabs %}

The syntax for using a generic type requires declaring that type symbol before the parameter list, so you add that:

{% tabs map-type-symbol-definition %}
{% tab 'Scala 2 and 3' %}
```scala
def map[A](f: (Int) => A)
```
{% endtab %}
{% endtabs %}

Next, you know that `map` should also accept a `List[Int]`:

{% tabs map-list-int-param-definition %}
{% tab 'Scala 2 and 3' %}
```scala
def map[A](f: (Int) => A, xs: List[Int])
```
{% endtab %}
{% endtabs %}

Finally, you also know that `map` returns a transformed `List` that contains elements of the generic type `A`:

{% tabs map-with-return-type-definition %}
{% tab 'Scala 2 and 3' %}
```scala
def map[A](f: (Int) => A, xs: List[Int]): List[A] = ???
```
{% endtab %}
{% endtabs %}

That takes care of the method signature.
Now all you have to do is write the method body.
A `map` method applies the function it’s given to every element in the list it’s given to produce a new, transformed list.
One way to do this is with a `for` expression:

{% tabs for-definition class=tabs-scala-version %}
{% tab 'Scala 2' %}
```scala
for (x <- xs) yield f(x)
```
{% endtab %}
{% tab 'Scala 3' %}
```scala
for x <- xs yield f(x)
```
{% endtab %}
{% endtabs %}

`for` expressions often make code surprisingly simple, and for our purposes, that ends up being the entire method body.

Putting it together with the method signature, you now have a standalone `map` method that works with a `List[Int]`:

{% tabs map-function class=tabs-scala-version %}
{% tab 'Scala 2' %}
```scala
def map[A](f: (Int) => A, xs: List[Int]): List[A] =
for (x <- xs) yield f(x)
```
{% endtab %}
{% tab 'Scala 3' %}
```scala
def map[A](f: (Int) => A, xs: List[Int]): List[A] =
for x <- xs yield f(x)
```
{% endtab %}
{% endtabs %}


### Make it generic

As a bonus, notice that the `for` expression doesn’t do anything that depends on the type inside the `List` being `Int`.
Therefore, you can replace `Int` in the type signature with the generic type parameter `B`:

{% tabs map-function-full-generic class=tabs-scala-version %}
{% tab 'Scala 2' %}
```scala
def map[A, B](f: (B) => A, xs: List[B]): List[A] =
for (x <- xs) yield f(x)
```
{% endtab %}
{% tab 'Scala 3' %}
```scala
def map[A, B](f: (B) => A, xs: List[B]): List[A] =
for x <- xs yield f(x)
```
{% endtab %}
{% endtabs %}

Now you have a `map` method that works with any `List`.

These examples demonstrate that `map` works as desired:

{% tabs map-use-example %}
{% tab 'Scala 2 and 3' %}
```scala
def double(i : Int) = i * 2
def double(i : Int): Int = i * 2
map(double, List(1, 2, 3)) // List(2, 4, 6)

def strlen(s: String) = s.length
def strlen(s: String): Int = s.length
map(strlen, List("a", "bb", "ccc")) // List(1, 2, 3)
```
{% endtab %}
{% endtabs %}

Now that you’ve seen how to write methods that accept functions as input parameters, let’s look at methods that return functions.

Expand Down