<style>
.reveal .code-wrapper {width: fit-content; max-width: 200%; font-size: xxx-large;}
.reveal img {max-width: 200%;}
.reveal pre {max-height: 600px;}
.reveal pre code {max-height: 600px; padding: 10px !important;}
.reveal .hljs-ln-numbers {display: none;}
code {color: #c7254e;}
.fold {position: relative; left: -130px;}
.tweaglogo {height: 60px; margin: 0 !important;}
.haskellatwork {position: relative; left: -450px;}
.list {position: relative; left: -90px; top: -70px;}
.traverse {position: relative; left: -90px;}
.traversePetFor {position: realtive; left: -40px;}
.traverseParseEmail {position: relative; left: -60px;}
.parseEmail {position: relative; left: -35px;}
.foldlM {position: relative; left: -90px;}
.httpCountDogs {position: relative; left: -115px;}
.reveal table th, .reveal table td {border-right: 1px solid; border-color: white;}
.reveal table thead tr th:last-child, .reveal table tbody tr td:last-child {border-right: none;}
.reveal table tr td:first-child {font-weight: bold;}
.highlight {color: #d9480f}
.backgrounds {background-image: url(https://github.com/marcosh/functional-loops/blob/main/images/Tweag_Preso_BGND.svg?raw=true);}
.reveal .slide-background {
background-image: url(https://github.com/marcosh/functional-loops/blob/main/images/T_Mark_Orange.svg?raw=true);
height: 50px;
width: 50px;
position: absolute;
top: 20px;
right: 35px;
}
</style>
# Looping Through Functional Loops
---
## Who am I?
:scroll: [marcosh.github.io](http://marcosh.github.io/)
:bird: [@marcoshuttle](https://twitter.com/marcoshuttle)
:elephant: [@marcosh@functional.cafe](https://functional.cafe/@marcosh)
[working at ![haskell at work](https://github.com/marcosh/functional-loops/blob/main/images/Tweag_AMCC_Logo_Orange.svg?raw=true)<!-- .element: class="tweaglogo"-->](https://www.tweag.io/)
---
[![haskell at work](https://github.com/marcosh/functional-loops/blob/main/images/haskellatworkheader.png?raw=true)<!-- .element: class="haskellatwork" -->](https://skillsmatter.com/workshops/883)
![qr code](https://github.com/marcosh/functional-loops/blob/main/images/Haskell%20at%20Work%20w%20Marco.png?raw=true)
---
![for loop](https://github.com/marcosh/functional-loops/blob/main/diagrams/forloop1.png?raw=true)
---
![for loop](https://github.com/marcosh/functional-loops/blob/main/diagrams/forloop2.png?raw=true)
---
![foreach](https://github.com/marcosh/functional-loops/blob/main/images/foreach.png?raw=true)
---
![list](https://github.com/marcosh/functional-loops/blob/main/diagrams/list0.png?raw=true)<!-- .element: class="list" -->
---
![list](https://github.com/marcosh/functional-loops/blob/main/diagrams/list1.png?raw=true)<!-- .element: class="list" -->
---
![list](https://github.com/marcosh/functional-loops/blob/main/diagrams/list2.png?raw=true)<!-- .element: class="list" -->
---
![list](https://github.com/marcosh/functional-loops/blob/main/diagrams/list3.png?raw=true)<!-- .element: class="list" -->
---
![list](https://github.com/marcosh/functional-loops/blob/main/diagrams/list4.png?raw=true)<!-- .element: class="list" -->
---
![list](https://github.com/marcosh/functional-loops/blob/main/diagrams/list5.png?raw=true)<!-- .element: class="list" -->
---
![list](https://github.com/marcosh/functional-loops/blob/main/diagrams/list6.png?raw=true)<!-- .element: class="list" -->
---
![list sugar](https://github.com/marcosh/functional-loops/blob/main/diagrams/listsugar.png?raw=true)
---
![list sugar](https://github.com/marcosh/functional-loops/blob/main/diagrams/listsugar1.png?raw=true)
---
![list sugar](https://github.com/marcosh/functional-loops/blob/main/diagrams/listsugar2.png?raw=true)
---
![list sugar](https://github.com/marcosh/functional-loops/blob/main/diagrams/listsugar3.png?raw=true)
---
```haskell
1 : (2 : (3 : (4 : (5 : [])))
```
---
![left associativity](https://github.com/marcosh/functional-loops/blob/main/diagrams/listassociativity.png?raw=true)
---
![left associativity](https://github.com/marcosh/functional-loops/blob/main/diagrams/listsyntacticsugar.png?raw=true)
---
```haskell [1|3|5]
names = ["George", "Marco", "Michael"]
for (i = 0; i++; i < names.length)
{
lengths[i] = names[i].length
}
```
---
## map
---
![map](https://github.com/marcosh/functional-loops/blob/main/diagrams/map0.png?raw=true)
---
![map](https://github.com/marcosh/functional-loops/blob/main/diagrams/map1.png?raw=true)
---
![map](https://github.com/marcosh/functional-loops/blob/main/diagrams/map2.png?raw=true)
---
![map](https://github.com/marcosh/functional-loops/blob/main/diagrams/map3.png?raw=true)
---
```haskell
map length ["George", "Marco", "Michael"]
```
---
![map names](https://github.com/marcosh/functional-loops/blob/main/diagrams/mapnames0.png?raw=true)
---
![map names](https://github.com/marcosh/functional-loops/blob/main/diagrams/mapnames1.png?raw=true)
---
![map names](https://github.com/marcosh/functional-loops/blob/main/diagrams/mapnames2.png?raw=true)
---
![map names](https://github.com/marcosh/functional-loops/blob/main/diagrams/mapnames3.png?raw=true)
---
![map names](https://github.com/marcosh/functional-loops/blob/main/diagrams/mapnames4.png?raw=true)
---
```haskell
map length ["George", "Marco", "Michael"]
-- [6, 5, 7]
```
---
## map
- access one element at the time
- apply a pure function to every element
---
```javascript [1|3|5|7]
numbers = [1, 2, 3, 4, 5]
sum = 0
for (i = 0; i++; i < numbers.length)
{
sum += numbers[i]
}
```
---
## fold
---
![fold](https://github.com/marcosh/functional-loops/blob/main/diagrams/fold0.png?raw=true)<!-- .element: class="fold" -->
---
![fold](https://github.com/marcosh/functional-loops/blob/main/diagrams/fold1.png?raw=true)<!-- .element: class="fold" -->
---
![fold](https://github.com/marcosh/functional-loops/blob/main/diagrams/fold2.png?raw=true)<!-- .element: class="fold" -->
---
![fold](https://github.com/marcosh/functional-loops/blob/main/diagrams/fold3.png?raw=true)<!-- .element: class="fold" -->
---
![fold](https://github.com/marcosh/functional-loops/blob/main/diagrams/fold4.png?raw=true)<!-- .element: class="fold" -->
---
```haskell
foldl (+) 0 [1, 2, 3, 4, 5]
```
---
![foldl](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldl0.png?raw=true)
---
![foldl](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldl1.png?raw=true)
---
![foldl](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldl2.png?raw=true)
---
![foldl](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldl3.png?raw=true)
---
![foldl](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldl4.png?raw=true)
---
![foldl](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldl5.png?raw=true)
---
```haskell
foldl (+) 0 [1, 2, 3, 4, 5]
-- ((((0 + 1) + 2) + 3) + 4) + 5
```
---
```haskell
foldl (+) 0 [1, 2, 3, 4, 5]
-- ((((0 + 1) + 2) + 3) + 4) + 5 = 15
```
---
![foldl'](https://github.com/marcosh/functional-loops/blob/main/diagrams/fold5.png?raw=true)<!-- .element: class="fold" -->
---
![foldl'](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldl'0.png?raw=true)
---
![foldl'](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldl'1.png?raw=true)
---
![foldl'](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldl'2.png?raw=true)
---
![foldl'](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldl'3.png?raw=true)
---
![foldl'](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldl'4.png?raw=true)
---
![foldl'](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldl'5.png?raw=true)
---
![foldr](https://github.com/marcosh/functional-loops/blob/main/diagrams/fold6.png?raw=true)<!-- .element: class="fold" -->
---
```haskell
foldr (+) 0 [1, 2, 3, 4, 5]
```
---
![foldr](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldr0.png?raw=true)
---
![foldr](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldr1.png?raw=true)
---
![foldr](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldr2.png?raw=true)
---
![foldr](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldr3.png?raw=true)
---
![foldr](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldr4.png?raw=true)
---
![foldr](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldr5.png?raw=true)
---
![foldr](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldr6.png?raw=true)
---
```haskell
foldr (+) 0 [1, 2, 3, 4, 5]
-- 1 + (2 + (3 + (4 + (5 + 0))))
```
---
```haskell
foldr (+) 0 [1, 2, 3, 4, 5]
-- 1 + (2 + (3 + (4 + (5 + 0)))) = 15
```
---
![foldr substitution](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldrsubstitution0.png?raw=true)
---
![foldr substitution](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldrsubstitution1.png?raw=true)
---
![foldr substitution](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldrsubstitution2.png?raw=true)
---
![foldr substitution](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldrsubstitution3.png?raw=true)
---
![foldr substitution](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldrsubstitution4.png?raw=true)
---
![foldr substitution](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldrsubstitution5.png?raw=true)
---
![foldr substitution](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldrsubstitution6.png?raw=true)
---
![foldr substitution](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldrsubstitution7.png?raw=true)
---
## fold
- accumulate elements
- pure function on accumulator and item
---
```javascript [1|3|5-7|9]
for (i = 0; i++; i < names.length)
{
pet = petFor(names[i])
if (pet == null) {
return null
}
pets[i] = pet
}
```
---
![petFor](https://github.com/marcosh/functional-loops/blob/main/diagrams/petFor1.png?raw=true)
---
![petFor](https://github.com/marcosh/functional-loops/blob/main/diagrams/petFor2.png?raw=true)
---
```haskell [1|2]
map petFor ["George", "Marco", "Michael"]
-- [Just "Dharma", Nothing, Just "Curry"]
```
---
## traverse
---
![traverse](https://github.com/marcosh/functional-loops/blob/main/diagrams/traverse0.png?raw=true)<!-- .element: class="traverse" -->
---
![traverse](https://github.com/marcosh/functional-loops/blob/main/diagrams/traverse1.png?raw=true)<!-- .element: class="traverse" -->
---
![traverse](https://github.com/marcosh/functional-loops/blob/main/diagrams/traverse2.png?raw=true)<!-- .element: class="traverse" -->
---
![traverse](https://github.com/marcosh/functional-loops/blob/main/diagrams/traverse3.png?raw=true)<!-- .element: class="traverse" -->
---
![traverse](https://github.com/marcosh/functional-loops/blob/main/diagrams/traverse4.png?raw=true)<!-- .element: class="traverse" -->
---
![traverse](https://github.com/marcosh/functional-loops/blob/main/diagrams/traverse5.png?raw=true)<!-- .element: class="traverse" -->
---
```haskell [1|2|4|5]
traverse petFor ["George", "Marco", "Michael"]
-- Nothing
traverse petFor ["George", "Michael"]
-- Just ["Dharma", "Curry"]
```
<!-- .element: class="traversePetFor" -->
---
```javascript [1|3|5-7|9]
for (i = 0; i++; i < emails.length)
{
isValid = validateEmail(emails[i])
if (!isValid) {
throw InvalidEmailException(emails[i])
}
validEmails[i] = emails[i]
}
```
---
![parse email](https://github.com/marcosh/functional-loops/blob/main/diagrams/parseEmail1.png?raw=true)<!-- .element: class="parseEmail" -->
---
![parse email](https://github.com/marcosh/functional-loops/blob/main/diagrams/parseEmail2.png?raw=true)<!-- .element: class="parseEmail" -->
---
```haskell
traverse
:: (String -> Either Error Email)
-> [String]
-> Either Error [Email]
```
---
```haskell [1|2|4|5]
traverse parseEmail ["foo@bar.it", "baz@jiz.fr"]
-- Right [_, _]
traverse parseEmail ["foo@bar.it", "notanemail"]
-- Left _
```
<!-- .element: class="traverseParseEmail" -->
---
```javascript [1|3]
for (i = 0; i++; i < names.length)
{
pets[i] = httpPetFor(names[i])
}
```
---
```haskell
httpPetFor :: Person -> IO Pet
```
---
```haskell
traverse
:: (Person -> IO Pet)
-> [Person]
-> IO [Pet]
```
---
```haskell [1|2]
traverse httpPetFor ["George", "Michael"]
-- ["Dharma", "Curry"]
```
---
```haskell
traverse
:: Applicative f
=> (a -> f b)
-> [a]
-> f [b]
---
```haskell
sequence
:: Applicative f
-> [f a]
-> f [a]
```
---
```haskell [1|3]
traverse = sequence . map
sequence = traverse id
```
---
## traverse
- access one element at the time
- perform an effectful computation for every element
---
```javascript [1|3|5|7-9]
countDogs = 0
for (i = 0; i++; i < names.length)
{
pet = httpPetFor(names[i])
if isDog(pet) {
countDogs++
}
}
```
---
## fold_M
---
![foldlM](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldlM0.png?raw=true)<!-- .element: class="foldlM" -->
---
![foldlM](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldlM1.png?raw=true)<!-- .element: class="foldlM" -->
---
![foldlM](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldlM2.png?raw=true)<!-- .element: class="foldlM" -->
---
![foldlM](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldlM3.png?raw=true)<!-- .element: class="foldlM" -->
---
![foldlM](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldlM4.png?raw=true)<!-- .element: class="foldlM" -->
---
![foldlM](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldlM5.png?raw=true)<!-- .element: class="foldlM" -->
---
![foldlM](https://github.com/marcosh/functional-loops/blob/main/diagrams/foldlM6.png?raw=true)<!-- .element: class="foldlM" -->
---
```haskell [1|3-6|7]
httpCountDogs :: Person -> Int -> IO Int
foldlM
httpCountDogs
0
["George", "Marco", "Michael"]
-- 1
```
---
```haskell
foldlM
:: Monad m
=> (b -> a -> m b)
-> b
-> [a]
-> m b
```
---
```haskell
foldrM
:: Monad m
=> (a -> b -> m b)
-> b
-> [a]
-> m b
```
---
## fold_M
- accumulate elements
- perform an effectful computation for every element
---
| | pure | effectful |
| ----------- | ----- | --------- |
| per element | | |
| aggregate | <span style="visibility: hidden;">fold_</span> | |
---
| | pure<!-- .element: class="highlight" --> | effectful |
| ----------- | ----- | --------- |
| per element<!-- .element: class="highlight" --> | | |
| aggregate | <span style="visibility: hidden;">fold_</span> | |
---
| | pure<!-- .element: class="highlight" --> | effectful |
| ----------- | ----- | --------- |
| per element<!-- .element: class="highlight" --> | map<!-- .element: class="highlight" --> | |
| aggregate | <span style="visibility: hidden;">fold_</span> | |
---
| | pure<!-- .element: class="highlight" --> | effectful |
| ----------- | ----- | --------- |
| per element | map | |
| aggregate<!-- .element: class="highlight" --> | <span style="visibility: hidden;">fold_</span> | |
---
| | pure<!-- .element: class="highlight" --> | effectful |
| ----------- | ----- | --------- |
| per element | map | |
| aggregate<!-- .element: class="highlight" --> | fold_<!-- .element: class="highlight" --> | |
---
| | pure | effectful<!-- .element: class="highlight" --> |
| ----------- | ----- | --------- |
| per element<!-- .element: class="highlight" --> | map | |
| aggregate | fold_ | |
---
| | pure | effectful<!-- .element: class="highlight" --> |
| ----------- | ----- | --------- |
| per element<!-- .element: class="highlight" --> | map | traverse<!-- .element: class="highlight" --> |
| aggregate | fold_ | |
---
| | pure | effectful<!-- .element: class="highlight" --> |
| ----------- | ----- | --------- |
| per element | map | traverse |
| aggregate<!-- .element: class="highlight" --> | fold_ | |
---
| | pure | effectful<!-- .element: class="highlight" --> |
| ----------- | ----- | --------- |
| per element | map | traverse |
| aggregate<!-- .element: class="highlight" --> | fold_ | fold_M<!-- .element: class="highlight" --> |
---
# THANK YOU
---
[![haskell at work](https://github.com/marcosh/functional-loops/blob/main/images/haskellatworkheader.png?raw=true)<!-- .element: class="haskellatwork" -->](https://skillsmatter.com/workshops/883)
![qr code](https://github.com/marcosh/functional-loops/blob/main/images/Haskell%20at%20Work%20w%20Marco.png?raw=true)
{"metaMigratedAt":"2023-06-17T12:51:00.502Z","metaMigratedFrom":"YAML","title":"Looping Through Functional Loops","breaks":true,"slideOptions":"{\"progress\":true,\"controls\":false,\"slideNumber\":false}","contributors":"[{\"id\":\"0893b955-bc9c-4ecc-b38c-6072b5bc1ecd\",\"add\":26382,\"del\":9318}]"}