Skip to content
This repository has been archived by the owner on Aug 10, 2020. It is now read-only.

One step in elm #28

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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
90 changes: 90 additions & 0 deletions _posts/2019-01-29-un-pas-de-plus-dans-elm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
layout: post
title: "Un pas de plus dans Elm grâce à la compréhension du foo.map"
excerpt: "Ma compréhension sur le langage a fait un bon en avant, quand j'ai réussi à comprendre les signatures de Maybe.map, Task.map, Decode.map. Du coup, j'ai pensé que je pourrais essayer de vous transmettre ma compréhension de .map (Decode.map, Maybe.map, Task.map, ...)."
date: 2019-01-29 23:07:00 +0100
categories: Elm
tags: elm map
---


# Un pas de plus dans Elm grâce à la compréhension du foo.map .

Ma compréhension sur le langage a fait un bon en avant, quand j'ai réussi à comprendre les signatures de Maybe.map, Task.map, Decode.map. Du coup, j'ai pensé que je pourrais essayer de vous transmettre ma compréhension de .map (Decode.map, Maybe.map, Task.map, ...).

```elm
Maybe.map : (a -> b) -> Maybe a -> Maybe b
```

Nous allons prendre comme exemple la première fonction *[(Maybe.map)](https://package.elm-lang.org/packages/elm/core/latest/Maybe#map)*.
Si nous nous reportons à sa signature, on voit que le premier paramètre est une fonction symbolisé par les `()`, et le second paramètre est un `Maybe a` et cela retourne un `Maybe b`.

## fonction .map

.map n'est ni plus ni moins qu'une fonction de transformation qui prend en premier paramètre la fonction de transformation et en second paramètre la donnée que vous souhaitez transformer pour retourner le résultat de cette transformation.

```
Maybe.map : (a -> b) -> Maybe a -> Maybe b
```

| Nom de la fonction | Premier paramètre | Second paramètre | Résultat de la transformation |
|:-:|:-:|:-:|:-:|
| Maybe.map | (a -> b) | Maybe a | Maybe b |

Nous allons retrouver toute la logique de transformation dans le premier paramètre. En le décomposant on peut voir que c'est une fonction qui prend en premier paramètre, le second paramètre `Maybe a` de `Maybe.map` et renverra le résultat de la transformation à savoir `Maybe b`.

Comme exemple je vais tenter de transformer mes fruits en jus du fruits. On part d'un nombre fruits incertains (je peux rentrer bredouille de la cueillette) pour ensuite le transformer en jus de fruits.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attention, la transformation en jus c'est souvent l'exemple utilisé pour reduce (fold). Ici pour pourrait préciser que le mapping s'assurera de prélever un dixième des fruits récoltés, si on en a.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ! je savais pas :(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Le map ça transforme plutôt des pommes en poire potentiellement non ? :p

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.



```
freshFruitJuice : Maybe Int -> Maybe Float
freshFruitJuice fruit =
Maybe.map (\f -> toFloat f * 0.1) fruit
```

Nous avons la possibilité aussi de passer plusieurs paramètres à notre fonction de transformation en utilisant map2, map3, map4

```
freshFruitJuice : Maybe Int -> Maybe Int -> Maybe Int -> Maybe Float
freshFruitJuice orange lemon carrots =
Maybe.map3 (\o l c -> (toFloat o + toFloat l + toFloat c) * 0.1) orange lemon carrots
```

Une fois que vous aurez compris cette partie là vous verrez que les Decode.map, Task.map, etc.. vous serrons beaucoup moins obscure.

Du coup maintenant si nous prenons un cas plus concret avec les decodeurs par exemple. Nous souhaitons transformer un payload json en User.
Nous avons utilisé `Decode.map3`

```
Decode.map3 : (a -> b -> c -> value) -> Decoder a -> Decoder b -> Decoder c -> Decoder value
```

afin d'avoir en paramètre l'id, le firstname, et lastname et de créer un record de type User.

```
type alias User =
{ id : String
, firstname : String
, lastname : String
}


decode : Decoder User
decode =
Decode.map3 (\id firstname lastname -> User id firstname lastname)
(Decode.field "id" Decode.string)
(Decode.field "firstname" Decode.string)
(Decode.field "lastname" Decode.string)

```

On peut utiliser le [currying](https://fr.wikipedia.org/wiki/Curryfication) pour construire le records `User` comme indiqué dans la [documentation](https://guide.elm-lang.org/types/type_aliases.html), j'ai volontairement souhaité ne pas aborder le sujet currying qui pourrait faire l'objet d'un autre article. Pour en revenir à la fonction decode, on peut là réécrire de cette manière là, c'est d'ailleurs celle-ci qui sera le plus souvent utilisé :

```
decode : Decoder User
decode =
Decode.map3 User
(Decode.field "id" Decode.string)
(Decode.field "firstname" Decode.string)
(Decode.field "lastname" Decode.string)
```