SlideShare a Scribd company logo
Based on definitions from
Left and Right Folds
Comparison of a mathematical definition
and a programmatic one
Polyglot FP for Fun and Profit - Haskell and Scala
@philip_schwarz
slides by https://www.slideshare.net/pjschwarz
Sergei Winitzki
sergei-winitzki-11a6431
Richard Bird
http://www.cs.ox.ac.uk/people/richard.bird/
π‘“π‘œπ‘™π‘‘π‘™ ∷ 𝛽 β†’ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘₯ ∢ π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯ π‘₯𝑠
π‘“π‘œπ‘™π‘‘π‘Ÿ ∷ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯ ∢ π‘₯𝑠 = 𝑓 π‘₯ π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠
If I have to write down the definitions of a left
fold and a right fold for lists, here is what I write
While both definitions are recursive, the left fold is tail recursive, whereas the right fold isn’t.
Although I am very familiar with the above definitions, and view them as doing a good job of
explaining the two folds, I am always interested in alternative ways of explaining things, and so
I have been looking at Sergei Winitzki’s mathematical definitions of left and right folds, in his
upcoming book: The Science of Functional Programming (SOFP).
Sergei’s definitions of the folds are in the top two rows of the following table
Sergei Winitzki
Richard Bird
@philip_schwarz
test1 = TestCase (assertEqual "foldl(+) 0 []" 0 (foldl (+) 0 []))
test2 = TestCase (assertEqual "foldl(+) 0 [1,2,3,4]" 10 (foldl (+) 0 [1,2,3,4]))
test3 = TestCase (assertEqual "foldr (+) 0 []" 0 (foldr (+) 0 []))
test4 = TestCase (assertEqual "foldr (+) 0 [1,2,3,4]" 10 (foldr (+) 0 [1,2,3,4]))
Left folds and right folds do not necessarily produce the same
results. According to the first duality theorem of folding, one case
in which the results are the same, is when we fold using the unit
and associative operation of a monoid.
First duality theorem. Suppose βŠ• is associative with unit 𝑒. Then
π‘“π‘œπ‘™π‘‘π‘Ÿ βŠ• 𝑒 π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ βŠ• 𝑒 π‘₯𝑠
For all finite lists π‘₯𝑠.
test5 = TestCase (assertEqual "foldl(-) 0 []" 0 (foldl (+) 0 []))
test6 = TestCase (assertEqual "foldl(-) 0 [1,2,3,4]" (- 10) (foldl (-) 0 [1,2,3,4]))
test7 = TestCase (assertEqual "foldr (-) 0 []" 0 (foldr (-) 0 []))
test8 = TestCase (assertEqual "foldr (-) 0 [1,2,3,4]" (- 2) (foldr (-) 0 [1,2,3,4]))
Folding integers left and right using the (Int,+,0) monoid, for example, produces the same results.
But folding integers left and right using subtraction and zero, does not produce the same results, and in
fact (Int,-,0) is not a monoid, because subtraction is not associative.
𝑓 = 𝑏; 𝑓 π‘₯ β§Ί 𝑠 = 𝑔(π‘₯, 𝑓(𝑠))
𝑓 = 𝑏; 𝑓 𝑠 β§Ί [π‘₯] = 𝑔(𝑓 𝑠 , π‘₯)
To avoid any confusion (the definitions use the same function name 𝑓), and to
align with the definitions on the right, let’s modify Sergei’s definitions by doing
some simple renaming.
Here are Sergei’s mathematical definitions again, on the right (the β§Ί operator
is list concatenation). Notice how neither definition is tail recursive. That is
deliberate.
As Sergei explained to me: β€œI'd like to avoid putting tail recursion into a
mathematical formula, because tail recursion is just a detail of how we
implement this function” and β€œThe fact that foldLeft is tail recursive for List is
an implementation detail that is specific to the List type. It will be different for
other sequence types. I do not want to put the implementation details into the
formulas.”
𝑓 β†’ π‘“π‘œπ‘™π‘‘π‘™ 𝑔 β†’ 𝑓 𝑏 β†’ 𝑒
π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯ β§Ί 𝑠 = 𝑓(π‘₯, π‘“π‘œπ‘™π‘‘π‘Ÿ(𝑠))
π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ 𝑠 β§Ί [π‘₯] = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑠 , π‘₯)
𝑓 β†’ π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑔 β†’ 𝑓 𝑏 β†’ 𝑒
π‘“π‘œπ‘™π‘‘π‘™ ∷ 𝛽 β†’ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘₯ ∢ π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯ π‘₯𝑠
π‘“π‘œπ‘™π‘‘π‘Ÿ ∷ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯ ∢ π‘₯𝑠 = 𝑓 π‘₯ π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠
𝑓 = 𝑏; 𝑓 π‘₯ β§Ί 𝑠 = 𝑔(π‘₯, 𝑓(𝑠))
𝑓 = 𝑏; 𝑓 𝑠 β§Ί [π‘₯] = 𝑔(𝑓 𝑠 , π‘₯)
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [ ] = 𝑒
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯ β§Ί 𝑠 = 𝑓 π‘₯ (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 𝑠)
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 𝑠 β§Ί [π‘₯] = 𝑓 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 𝑠 π‘₯
π‘“π‘œπ‘™π‘‘π‘™ :: (𝑏 β†’ π‘Ž β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘Žπ‘  = 𝑓 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 (𝑖𝑛𝑖𝑑 π‘Žπ‘ ) (π‘™π‘Žπ‘ π‘‘ π‘Žπ‘ )
π‘“π‘œπ‘™π‘‘π‘Ÿ :: (π‘Ž β†’ 𝑏 β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘Žπ‘  = 𝑓 β„Žπ‘’π‘Žπ‘‘ π‘Žπ‘  π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 (π‘‘π‘Žπ‘–π‘™ π‘Žπ‘ )
π‘“π‘œπ‘™π‘‘π‘™ :: (𝑏 β†’ π‘Ž β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘Žπ‘  = 𝑓 𝑏 π‘Ž
π‘€β„Žπ‘’π‘Ÿπ‘’ π‘Ž = π‘™π‘Žπ‘ π‘‘ π‘Žπ‘ 
𝑏 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 (𝑖𝑛𝑖𝑑 π‘Žπ‘ )
π‘“π‘œπ‘™π‘‘π‘Ÿ :: (π‘Ž β†’ 𝑏 β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘Žπ‘  = 𝑓 π‘Ž 𝑏
π‘€β„Žπ‘’π‘Ÿπ‘’ π‘Ž = β„Žπ‘’π‘Žπ‘‘ π‘Žπ‘ 
𝑏 = π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 (π‘‘π‘Žπ‘–π‘™ π‘Žπ‘ )
π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯ β§Ί 𝑠 = 𝑓(π‘₯, π‘“π‘œπ‘™π‘‘π‘Ÿ(𝑠))
π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ 𝑠 β§Ί [π‘₯] = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑠 , π‘₯)
To help us understand the above two definitions, let’s first express them in Haskell,
pretending that we are able to use 𝑠 β§Ί [π‘₯] and π‘₯ β§Ί 𝑠 in a pattern match.
Now let’s replace 𝑠 β§Ί [π‘₯] and π‘₯ β§Ί 𝑠 with as, and get the functions to extract
the 𝑠 and the π‘₯ using the β„Žπ‘’π‘Žπ‘‘, π‘‘π‘Žπ‘–π‘™, π‘™π‘Žπ‘ π‘‘ and 𝑖𝑛𝑖𝑑. Let’s also add type signatures
And now let’s make it more obvious that what each fold is doing is taking an π‘Ž from the list,
folding the rest of the list into a 𝑏, and then returning the result of calling 𝑓 with π‘Ž and 𝑏.
π‘“π‘œπ‘™π‘‘π‘™ :: (𝑏 β†’ π‘Ž β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘Žπ‘  = 𝑓 𝑏 π‘Ž
π‘€β„Žπ‘’π‘Ÿπ‘’ π‘Ž = π‘™π‘Žπ‘ π‘‘ π‘Žπ‘ 
𝑏 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 (𝑖𝑛𝑖𝑑 π‘Žπ‘ )
π‘“π‘œπ‘™π‘‘π‘Ÿ :: (π‘Ž β†’ 𝑏 β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘Žπ‘  = 𝑓 π‘Ž 𝑏
π‘€β„Žπ‘’π‘Ÿπ‘’ π‘Ž = β„Žπ‘’π‘Žπ‘‘ π‘Žπ‘ 
𝑏 = π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 (π‘‘π‘Žπ‘–π‘™ π‘Žπ‘ )
Since the above two functions are very similar, let’s extract their common logic into a fold function. Let’s call the function
that is used to extract an element from the list π‘‘π‘Žπ‘˜π‘’, and the function that is used to extract the rest of the list π‘Ÿπ‘’π‘ π‘‘.
π‘“π‘œπ‘™π‘‘ ::	(𝑏 β†’ π‘Ž β†’ 𝑏)	β†’ ([π‘Ž]	β†’ π‘Ž)	β†’ ([π‘Ž]	β†’ [π‘Ž])	β†’ 𝑏 β†’ [π‘Ž]	β†’ 𝑏
π‘“π‘œπ‘™π‘‘ 𝑓 π‘‘π‘Žπ‘˜π‘’ π‘Ÿπ‘’π‘ π‘‘ 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘ 𝑓 π‘‘π‘Žπ‘˜π‘’ π‘Ÿπ‘’π‘ π‘‘ 𝑒 π‘Žπ‘  = 𝑓 𝑏 π‘Ž
π‘€β„Žπ‘’π‘Ÿπ‘’ π‘Ž = π‘‘π‘Žπ‘˜π‘’ π‘Žπ‘ 
𝑏 = π‘“π‘œπ‘™π‘‘ 𝑓 π‘‘π‘Žπ‘˜π‘’ π‘Ÿπ‘’π‘ π‘‘ 𝑒 (π‘Ÿπ‘’π‘ π‘‘ π‘Žπ‘ )
We can now define left and right
folds in terms of π‘“π‘œπ‘™π‘‘.
π‘“π‘œπ‘™π‘‘π‘™ :: (𝑏 β†’ π‘Ž β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 = π‘“π‘œπ‘™π‘‘ 𝑓 π‘™π‘Žπ‘ π‘‘ 𝑖𝑛𝑖𝑑
π‘“π‘œπ‘™π‘‘π‘Ÿ :: (π‘Ž β†’ 𝑏 β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 = π‘“π‘œπ‘™π‘‘ 𝑓𝑙𝑖𝑝 𝑓 β„Žπ‘’π‘Žπ‘‘ π‘‘π‘Žπ‘–π‘™
𝑓𝑙𝑖𝑝 ::	(π‘Ž β†’ 𝑏 β†’ 𝑐)	β†’ 𝑏 β†’ π‘Ž β†’ 𝑐
𝑓𝑙𝑖𝑝 𝑓 π‘₯ 𝑦 =	𝑓 𝑦 π‘₯
The slightly perplexing thing is that while a left fold applies 𝑓 to list elements starting with the β„Žπ‘’π‘Žπ‘‘ of the list and
proceeding from left to right, the above π‘“π‘œπ‘™π‘‘π‘™ function achieves that by navigating through list elements from right to left.
Third duality theorem. For all finite lists π‘₯𝑠,
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓𝑙𝑖𝑝 𝑓 𝑒 (π‘Ÿπ‘’π‘£π‘’π‘Ÿπ‘ π‘’ π‘₯𝑠)
π’˜π’‰π’†π’“π’† 𝑓𝑙𝑖𝑝 𝑓 π‘₯ 𝑦 = 𝑓 𝑦 π‘₯
The fact that we can define π‘“π‘œπ‘™π‘‘π‘™ and π‘“π‘œπ‘™π‘‘π‘Ÿ in terms of π‘“π‘œπ‘™π‘‘, as we
do above, seems related to the third duality theorem of folding.
Instead of our π‘“π‘œπ‘™π‘‘π‘™ function being passed the reverse of the list
passed to π‘“π‘œπ‘™π‘‘π‘Ÿ, it processes the list with π‘™π‘Žπ‘ π‘‘ and 𝑖𝑛𝑖𝑑, rather than
with β„Žπ‘’π‘Žπ‘‘ and π‘‘π‘Žπ‘–π‘™.
@philip_schwarz
To summarise what we did to help understand SOFP’s mathematical definitions of left and right fold: we
turned them into code and expressed them in terms of a common function π‘“π‘œπ‘™π‘‘ that uses a π‘‘π‘Žπ‘˜π‘’ function
to extract an element from the list being folded, and a π‘Ÿπ‘’π‘ π‘‘ function to extract the rest of the list.
π‘“π‘œπ‘™π‘‘ ::	(𝑏 β†’ π‘Ž β†’ 𝑏)	β†’ ([π‘Ž]	β†’ π‘Ž)	β†’ ([π‘Ž]	β†’ [π‘Ž])	β†’ 𝑏 β†’ [π‘Ž]	β†’ 𝑏
π‘“π‘œπ‘™π‘‘ 𝑓 π‘‘π‘Žπ‘˜π‘’ π‘Ÿπ‘’π‘ π‘‘ 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘ 𝑓 π‘‘π‘Žπ‘˜π‘’ π‘Ÿπ‘’π‘ π‘‘ 𝑒 π‘Žπ‘  = 𝑓 𝑏 π‘Ž
π‘€β„Žπ‘’π‘Ÿπ‘’ π‘Ž = π‘‘π‘Žπ‘˜π‘’ π‘Žπ‘ 
𝑏 = π‘“π‘œπ‘™π‘‘ 𝑓 π‘‘π‘Žπ‘˜π‘’ π‘Ÿπ‘’π‘ π‘‘ 𝑒 (π‘Ÿπ‘’π‘ π‘‘ π‘Žπ‘ )
π‘“π‘œπ‘™π‘‘π‘™ :: (𝑏 β†’ π‘Ž β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 = π‘“π‘œπ‘™π‘‘ 𝑓 π‘™π‘Žπ‘ π‘‘ 𝑖𝑛𝑖𝑑
π‘“π‘œπ‘™π‘‘π‘Ÿ :: (π‘Ž β†’ 𝑏 β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 = π‘“π‘œπ‘™π‘‘ 𝑓𝑙𝑖𝑝 𝑓 β„Žπ‘’π‘Žπ‘‘ π‘‘π‘Žπ‘–π‘™
π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯ β§Ί 𝑠 = 𝑓(π‘₯, π‘“π‘œπ‘™π‘‘π‘Ÿ(𝑠))
π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ 𝑠 β§Ί [π‘₯] = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑠 , π‘₯)
π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘Žπ‘  = 𝑓(β„Žπ‘’π‘Žπ‘‘(π‘Žπ‘ ), π‘“π‘œπ‘™π‘‘π‘Ÿ(π‘‘π‘Žπ‘–π‘™(π‘Žπ‘ )))
π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ π‘Žπ‘  = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑖𝑛𝑖𝑑(π‘Žπ‘ ) , π‘™π‘Žπ‘ π‘‘(π‘Žπ‘ ))
Let’s feed one aspect of the above back into Sergei’s definitions. Let’s temporarily rewrite them by
replacing 𝑠 β§Ί [π‘₯] and π‘₯ β§Ί 𝑠 with as, and getting the definitions to extract the 𝑠 and the π‘₯ using the
functions β„Žπ‘’π‘Žπ‘‘, π‘‘π‘Žπ‘–π‘™, π‘™π‘Žπ‘ π‘‘ and 𝑖𝑛𝑖𝑑.
Notice how the flipping of 𝑓 done by the π‘“π‘œπ‘™π‘‘π‘Ÿ function above, is reflected, in the π‘“π‘œπ‘™π‘‘π‘Ÿ function below,
in the fact that its 𝑓 takes an π‘Ž and a 𝑏, rather than a 𝑏 and an π‘Ž.
Another thing we can do to understand SOFP’s definitions of left and right folds, is to see how they work
when applied to a sample list, e.g. [π‘₯0, π‘₯1, π‘₯2, π‘₯3], when we run them manually.
In the next slide we first do this for the following definitions
π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ 𝑠 β§Ί [π‘₯] = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑠 , π‘₯) π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯ β§Ί 𝑠 = 𝑓(π‘₯, π‘“π‘œπ‘™π‘‘π‘Ÿ(𝑠))
π‘“π‘œπ‘™π‘‘π‘™ ∷ 𝛽 β†’ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘₯ ∢ π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯ π‘₯𝑠
π‘“π‘œπ‘™π‘‘π‘Ÿ ∷ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯ ∢ π‘₯𝑠 = 𝑓 π‘₯ π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠
In the slide after that, we do it for SOFP’s definitions.
∢
/ 
π‘₯0 ∢
/ 
π‘₯1 ∢
/ 
π‘₯2 ∢
/ 
π‘₯3
𝑓
/ 
𝑓 π‘₯3
/ 
𝑓 π‘₯2
/ 
𝑓 π‘₯1
/ 
𝑒 π‘₯0
𝑓
/ 
π‘₯0 𝑓
/ 
π‘₯1 𝑓
/ 
π‘₯2 𝑓
/ 
π‘₯3 𝑒
π‘₯0: (π‘₯1: π‘₯2: π‘₯3: )
𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 π‘₯3
var π‘Žπ‘π‘ = 𝑒
foreach(π‘₯ in π‘₯s)
π‘Žπ‘π‘ = 𝑓(π‘Žπ‘π‘, π‘₯)
return π‘Žπ‘π‘
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘₯𝑠
π‘₯𝑠 = [π‘₯0, π‘₯1, π‘₯2, π‘₯3]
π‘“π‘œπ‘™π‘‘π‘Ÿ ∷ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯: π‘₯𝑠 = 𝑓 π‘₯ π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠
π‘“π‘œπ‘™π‘‘π‘™ ∷ 𝛽 β†’ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘₯: π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯ π‘₯𝑠
π‘Ÿπ‘’π‘π‘™π‘Žπ‘π‘’:
∢ π‘€π‘–π‘‘β„Ž 𝑓
π‘€π‘–π‘‘β„Ž 𝑒
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯0, π‘₯1, π‘₯2, π‘₯3]
𝑓 π‘₯0 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯1, π‘₯2, π‘₯3]
𝑓 π‘₯0 (𝑓 π‘₯1 (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯2, π‘₯3]))
𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯3])))
𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (𝑓 π‘₯3 (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [ ]))))
𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (𝑓 π‘₯3 𝑒)))
𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (𝑓 π‘₯3 𝑒)))
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 [π‘₯0, π‘₯1, π‘₯2, π‘₯3]
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯0 [π‘₯1, π‘₯2, π‘₯3]
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 [π‘₯2, π‘₯3]
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 [π‘₯3]
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 π‘₯3 [ ]
𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 π‘₯3
∢
/ 
π‘₯0 ∢
/ 
π‘₯1 ∢
/ 
π‘₯2 ∢
/ 
π‘₯3
𝑓
/ 
𝑓 π‘₯3
/ 
𝑓 π‘₯2
/ 
𝑓 π‘₯1
/ 
𝑒 π‘₯0
𝑓
/ 
π‘₯0 𝑓
/ 
π‘₯1 𝑓
/ 
π‘₯2 𝑓
/ 
π‘₯3 𝑒
π‘₯0: (π‘₯1: π‘₯2: π‘₯3: )
𝑓(𝑓 𝑓 𝑓 𝑒, π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3)
π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯𝑠
π‘“π‘œπ‘™π‘‘π‘™ π‘₯𝑠
π‘₯𝑠 = [π‘₯0, π‘₯1, π‘₯2, π‘₯3]
𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, 𝑓(π‘₯3, 𝑒))))
π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ 𝑠 β§Ί [π‘₯] = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑠 , π‘₯)
π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯ β§Ί 𝑠 = 𝑓(π‘₯, π‘“π‘œπ‘™π‘‘π‘Ÿ(𝑠))
π‘“π‘œπ‘™π‘‘π‘™ π‘₯0, π‘₯1, π‘₯2, π‘₯3 ,
𝑓 π‘“π‘œπ‘™π‘‘π‘™ π‘₯0, π‘₯1, π‘₯2 , π‘₯3
𝑓(𝑓(π‘“π‘œπ‘™π‘‘π‘™ [π‘₯0, π‘₯1] , π‘₯2), π‘₯3)
𝑓 𝑓 𝑓 π‘“π‘œπ‘™π‘‘π‘™ π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3
𝑓 𝑓 𝑓 𝑓 π‘“π‘œπ‘™π‘‘π‘™ [ ] , π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3
𝑓 𝑓 𝑓 𝑓 𝑒, π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3
π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯0, π‘₯1, π‘₯2, π‘₯3])
𝑓(π‘₯0, π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯1, π‘₯2, π‘₯3]))
𝑓(π‘₯0, 𝑓(π‘₯1, π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯2, π‘₯3])))
𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯3]))))
𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, 𝑓(π‘₯3, π‘“π‘œπ‘™π‘‘π‘Ÿ([])))))
𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, 𝑓(π‘₯3, 𝑒))))
π‘“π‘œπ‘™π‘‘π‘™ ∷ 𝛽 β†’ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘₯: π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯ π‘₯𝑠
π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ 𝑠 β§Ί [π‘₯] = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑠 , π‘₯)
∢
/ 
π‘₯0 ∢
/ 
π‘₯1 ∢
/ 
π‘₯2 ∢
/ 
π‘₯3
π‘₯0: (π‘₯1: π‘₯2: π‘₯3: )
π‘₯𝑠 = [π‘₯0, π‘₯1, π‘₯2, π‘₯3]
𝑓
/ 
𝑓 π‘₯3
/ 
𝑓 π‘₯2
/ 
𝑓 π‘₯1
/ 
𝑒 π‘₯0
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 [π‘₯0, π‘₯1, π‘₯2, π‘₯3]
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯0 [π‘₯1, π‘₯2, π‘₯3]
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 [π‘₯2, π‘₯3]
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 [π‘₯3]
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 π‘₯3 [ ]
𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 π‘₯3
π‘“π‘œπ‘™π‘‘π‘™ π‘₯0, π‘₯1, π‘₯2, π‘₯3 ,
𝑓 π‘“π‘œπ‘™π‘‘π‘™ π‘₯0, π‘₯1, π‘₯2 , π‘₯3
𝑓(𝑓(π‘“π‘œπ‘™π‘‘π‘™ [π‘₯0, π‘₯1] , π‘₯2), π‘₯3)
𝑓 𝑓 𝑓 π‘“π‘œπ‘™π‘‘π‘™ π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3
𝑓 𝑓 𝑓 𝑓 π‘“π‘œπ‘™π‘‘π‘™ [ ] , π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3
𝑓 𝑓 𝑓 𝑓 𝑒, π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3
Now let’s compare the results for both
definitions of π‘“π‘œπ‘™π‘‘π‘™. The results are the same.
@philip_schwarz
𝑓
/ 
π‘₯0 𝑓
/ 
π‘₯1 𝑓
/ 
π‘₯2 𝑓
/ 
π‘₯3 𝑒
π‘“π‘œπ‘™π‘‘π‘Ÿ ∷ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯: π‘₯𝑠 = 𝑓 π‘₯ π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯0, π‘₯1, π‘₯2, π‘₯3]
𝑓 π‘₯0 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯1, π‘₯2, π‘₯3]
𝑓 π‘₯0 (𝑓 π‘₯1 (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯2, π‘₯3]))
𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯3])))
𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (𝑓 π‘₯3 (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [ ]))))
𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (𝑓 π‘₯3 𝑒)))
π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯ β§Ί 𝑠 = 𝑓(π‘₯, π‘“π‘œπ‘™π‘‘π‘Ÿ(𝑠))
π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯0, π‘₯1, π‘₯2, π‘₯3])
𝑓(π‘₯0, π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯1, π‘₯2, π‘₯3]))
𝑓(π‘₯0, 𝑓(π‘₯1, π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯2, π‘₯3])))
𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯3]))))
𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, 𝑓(π‘₯3, π‘“π‘œπ‘™π‘‘π‘Ÿ([])))))
𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, 𝑓(π‘₯3, 𝑒))))
∢
/ 
π‘₯0 ∢
/ 
π‘₯1 ∢
/ 
π‘₯2 ∢
/ 
π‘₯3
π‘₯0: (π‘₯1: π‘₯2: π‘₯3: )
π‘₯𝑠 = [π‘₯0, π‘₯1, π‘₯2, π‘₯3]
And now let’s compare the results for both
definitions of π‘“π‘œπ‘™π‘‘π‘Ÿ. Again, the results are the same.
The way π‘“π‘œπ‘™π‘‘π‘Ÿ applies 𝑓 to π‘₯, 𝑦, z is by associating to the right.
The way π‘“π‘œπ‘™π‘‘π‘™ does it is by associating to the right.
Thinking of 𝑓 as an infix operator can help to grasp this.
π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓(π‘₯, 𝑓(𝑦, 𝑧)) π‘₯ βŠ• 𝑦 βŠ• 𝑧
π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 π‘₯, 𝑦 , 𝑧 (π‘₯ βŠ• 𝑦) βŠ• 𝑧
π‘“π‘œπ‘™π‘‘π‘Ÿ βŠ• 𝑒 π‘₯, 𝑦, z = π‘₯ βŠ• (𝑦 βŠ• 𝑧 βŠ• 𝑒 )
π‘“π‘œπ‘™π‘‘π‘Ÿ (+) 0 [1,2,3] = 1 + (2 + (3 + 0)) = 6
π‘“π‘œπ‘™π‘‘π‘™ (+) 0 [1,2,3] = ((0 + 1) + 2) + 3 = 6
π‘“π‘œπ‘™π‘‘π‘Ÿ βˆ’ 0 1,2,3 = 1 βˆ’ (2 βˆ’ (3 βˆ’ 0)) = 2
π‘“π‘œπ‘™π‘‘π‘™ βˆ’ 0 1,2,3 = ((0 βˆ’ 1) βˆ’ 2) βˆ’ 3 = βˆ’6
βŠ•
/ 
π‘₯ βŠ•
/ 
𝑦 βŠ•
/ 
𝑧 𝑒
βŠ•
/ 
βŠ• 𝑧
/ 
βŠ• 𝑦
/ 
𝑒 π‘₯
π‘“π‘œπ‘™π‘‘π‘™ βŠ• 𝑒 π‘₯, 𝑦, 𝑧 = ((𝑒 βŠ• π‘₯) βŠ• 𝑦) βŠ• 𝑧
Addition is associative, so associating to the left and to the right yields the
same result. But subtraction isn’t associative, so associating to the left yields
a result that is different to the one yielded when associating to the right.
We have seen that Sergei’s definitions of left and right folds make perfect sense.
Not only are they simple and succinct, they are also free of implementation details like tail recursion.
That’s all. I hope you found this slide deck useful.
By the way, in case you are interested, see below for a whole series of slide decks dedicated to folding.

More Related Content

What's hot

Applicative Functor
Applicative FunctorApplicative Functor
Applicative Functor
Philip Schwarz
Β 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Philip Schwarz
Β 
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Philip Schwarz
Β 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Philip Schwarz
Β 
Ad hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and CatsAd hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and Cats
Philip Schwarz
Β 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
Philip Schwarz
Β 
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Philip Schwarz
Β 
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
Philip Schwarz
Β 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Philip Schwarz
Β 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Philip Schwarz
Β 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Philip Schwarz
Β 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
Philip Schwarz
Β 
The Expression Problem - Part 2
The Expression Problem - Part 2The Expression Problem - Part 2
The Expression Problem - Part 2
Philip Schwarz
Β 
Sierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and Scala
Sierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and ScalaSierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and Scala
Sierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and Scala
Philip Schwarz
Β 
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
Natan Silnitsky
Β 
The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1
Philip Schwarz
Β 
Monad Laws Must be Checked
Monad Laws Must be CheckedMonad Laws Must be Checked
Monad Laws Must be Checked
Philip Schwarz
Β 
Blazing Fast, Pure Effects without Monads β€” LambdaConf 2018
Blazing Fast, Pure Effects without Monads β€” LambdaConf 2018Blazing Fast, Pure Effects without Monads β€” LambdaConf 2018
Blazing Fast, Pure Effects without Monads β€” LambdaConf 2018
John De Goes
Β 
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Philip Schwarz
Β 
Computer Graphics in Java and Scala - Part 1
Computer Graphics in Java and Scala - Part 1Computer Graphics in Java and Scala - Part 1
Computer Graphics in Java and Scala - Part 1
Philip Schwarz
Β 

What's hot (20)

Applicative Functor
Applicative FunctorApplicative Functor
Applicative Functor
Β 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Β 
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Β 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Β 
Ad hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and CatsAd hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and Cats
Β 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
Β 
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Β 
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
Β 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Β 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Β 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Β 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
Β 
The Expression Problem - Part 2
The Expression Problem - Part 2The Expression Problem - Part 2
The Expression Problem - Part 2
Β 
Sierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and Scala
Sierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and ScalaSierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and Scala
Sierpinski Triangle - Polyglot FP for Fun and Profit - Haskell and Scala
Β 
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
Β 
The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1
Β 
Monad Laws Must be Checked
Monad Laws Must be CheckedMonad Laws Must be Checked
Monad Laws Must be Checked
Β 
Blazing Fast, Pure Effects without Monads β€” LambdaConf 2018
Blazing Fast, Pure Effects without Monads β€” LambdaConf 2018Blazing Fast, Pure Effects without Monads β€” LambdaConf 2018
Blazing Fast, Pure Effects without Monads β€” LambdaConf 2018
Β 
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Β 
Computer Graphics in Java and Scala - Part 1
Computer Graphics in Java and Scala - Part 1Computer Graphics in Java and Scala - Part 1
Computer Graphics in Java and Scala - Part 1
Β 

Similar to Left and Right Folds - Comparison of a mathematical definition and a programmatic one - Polyglot FP for Fun and Profit - Haskell and Scala

Folding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a seriesFolding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a series
Philip Schwarz
Β 
Dual Spaces of Generalized Cesaro Sequence Space and Related Matrix Mapping
Dual Spaces of Generalized Cesaro Sequence Space and Related Matrix MappingDual Spaces of Generalized Cesaro Sequence Space and Related Matrix Mapping
Dual Spaces of Generalized Cesaro Sequence Space and Related Matrix Mapping
inventionjournals
Β 
Differential Geometry for Machine Learning
Differential Geometry for Machine LearningDifferential Geometry for Machine Learning
Differential Geometry for Machine Learning
SEMINARGROOT
Β 
Basic calculus (ii) recap
Basic calculus (ii) recapBasic calculus (ii) recap
Basic calculus (ii) recap
Farzad Javidanrad
Β 
Semana 24 funciones iv Γ‘lgebra uni ccesa007
Semana 24 funciones iv Γ‘lgebra uni ccesa007Semana 24 funciones iv Γ‘lgebra uni ccesa007
Semana 24 funciones iv Γ‘lgebra uni ccesa007
Demetrio Ccesa Rayme
Β 
On ranges and null spaces of a special type of operator named 𝝀 βˆ’ π’‹π’†π’„π’•π’Šπ’π’. – ...
On ranges and null spaces of a special type of operator named 𝝀 βˆ’ π’‹π’†π’„π’•π’Šπ’π’. – ...On ranges and null spaces of a special type of operator named 𝝀 βˆ’ π’‹π’†π’„π’•π’Šπ’π’. – ...
On ranges and null spaces of a special type of operator named 𝝀 βˆ’ π’‹π’†π’„π’•π’Šπ’π’. – ...
IJMER
Β 
Folding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a seriesFolding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a series
Philip Schwarz
Β 
Folding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a seriesFolding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a series
Philip Schwarz
Β 
E0561719
E0561719E0561719
E0561719
IOSR Journals
Β 
Teoria NumΓ©rica (Palestra 01)
Teoria NumΓ©rica (Palestra 01)Teoria NumΓ©rica (Palestra 01)
Teoria NumΓ©rica (Palestra 01)
Eugenio Souza
Β 
PRODUCT RULES
PRODUCT RULESPRODUCT RULES
PRODUCT RULES
NumanUsama
Β 
Matrix Transformations on Some Difference Sequence Spaces
Matrix Transformations on Some Difference Sequence SpacesMatrix Transformations on Some Difference Sequence Spaces
Matrix Transformations on Some Difference Sequence Spaces
IOSR Journals
Β 
Recurrence relation of Bessel's and Legendre's function
Recurrence relation of Bessel's and Legendre's functionRecurrence relation of Bessel's and Legendre's function
Recurrence relation of Bessel's and Legendre's function
Partho Ghosh
Β 
3 capitulo-iii-matriz-asociada-sem-14-t-l-d
3 capitulo-iii-matriz-asociada-sem-14-t-l-d3 capitulo-iii-matriz-asociada-sem-14-t-l-d
3 capitulo-iii-matriz-asociada-sem-14-t-l-d
FernandoDanielMamani1
Β 
Further Results On The Basis Of Cauchy’s Proper Bound for the Zeros of Entire...
Further Results On The Basis Of Cauchy’s Proper Bound for the Zeros of Entire...Further Results On The Basis Of Cauchy’s Proper Bound for the Zeros of Entire...
Further Results On The Basis Of Cauchy’s Proper Bound for the Zeros of Entire...
IJMER
Β 
Generalized Laplace - Mellin Integral Transformation
Generalized Laplace - Mellin Integral TransformationGeneralized Laplace - Mellin Integral Transformation
Generalized Laplace - Mellin Integral Transformation
IJERA Editor
Β 
Relativity
RelativityRelativity
Relativity
edgardoangeles1
Β 
Change variablethm
Change variablethmChange variablethm
Change variablethm
Jasonleav
Β 
MT102 Π›Π΅ΠΊΡ† 4
MT102 Π›Π΅ΠΊΡ† 4MT102 Π›Π΅ΠΊΡ† 4
MT102 Π›Π΅ΠΊΡ† 4
ssuser184df1
Β 

Similar to Left and Right Folds - Comparison of a mathematical definition and a programmatic one - Polyglot FP for Fun and Profit - Haskell and Scala (20)

Folding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a seriesFolding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a series
Β 
Dual Spaces of Generalized Cesaro Sequence Space and Related Matrix Mapping
Dual Spaces of Generalized Cesaro Sequence Space and Related Matrix MappingDual Spaces of Generalized Cesaro Sequence Space and Related Matrix Mapping
Dual Spaces of Generalized Cesaro Sequence Space and Related Matrix Mapping
Β 
Differential Geometry for Machine Learning
Differential Geometry for Machine LearningDifferential Geometry for Machine Learning
Differential Geometry for Machine Learning
Β 
Basic calculus (ii) recap
Basic calculus (ii) recapBasic calculus (ii) recap
Basic calculus (ii) recap
Β 
Semana 24 funciones iv Γ‘lgebra uni ccesa007
Semana 24 funciones iv Γ‘lgebra uni ccesa007Semana 24 funciones iv Γ‘lgebra uni ccesa007
Semana 24 funciones iv Γ‘lgebra uni ccesa007
Β 
On ranges and null spaces of a special type of operator named 𝝀 βˆ’ π’‹π’†π’„π’•π’Šπ’π’. – ...
On ranges and null spaces of a special type of operator named 𝝀 βˆ’ π’‹π’†π’„π’•π’Šπ’π’. – ...On ranges and null spaces of a special type of operator named 𝝀 βˆ’ π’‹π’†π’„π’•π’Šπ’π’. – ...
On ranges and null spaces of a special type of operator named 𝝀 βˆ’ π’‹π’†π’„π’•π’Šπ’π’. – ...
Β 
Folding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a seriesFolding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a series
Β 
Folding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a seriesFolding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a series
Β 
E0561719
E0561719E0561719
E0561719
Β 
Teoria NumΓ©rica (Palestra 01)
Teoria NumΓ©rica (Palestra 01)Teoria NumΓ©rica (Palestra 01)
Teoria NumΓ©rica (Palestra 01)
Β 
PRODUCT RULES
PRODUCT RULESPRODUCT RULES
PRODUCT RULES
Β 
Matrix Transformations on Some Difference Sequence Spaces
Matrix Transformations on Some Difference Sequence SpacesMatrix Transformations on Some Difference Sequence Spaces
Matrix Transformations on Some Difference Sequence Spaces
Β 
Recurrence relation of Bessel's and Legendre's function
Recurrence relation of Bessel's and Legendre's functionRecurrence relation of Bessel's and Legendre's function
Recurrence relation of Bessel's and Legendre's function
Β 
3 capitulo-iii-matriz-asociada-sem-14-t-l-d
3 capitulo-iii-matriz-asociada-sem-14-t-l-d3 capitulo-iii-matriz-asociada-sem-14-t-l-d
3 capitulo-iii-matriz-asociada-sem-14-t-l-d
Β 
Further Results On The Basis Of Cauchy’s Proper Bound for the Zeros of Entire...
Further Results On The Basis Of Cauchy’s Proper Bound for the Zeros of Entire...Further Results On The Basis Of Cauchy’s Proper Bound for the Zeros of Entire...
Further Results On The Basis Of Cauchy’s Proper Bound for the Zeros of Entire...
Β 
Generalized Laplace - Mellin Integral Transformation
Generalized Laplace - Mellin Integral TransformationGeneralized Laplace - Mellin Integral Transformation
Generalized Laplace - Mellin Integral Transformation
Β 
Relativity
RelativityRelativity
Relativity
Β 
Change variablethm
Change variablethmChange variablethm
Change variablethm
Β 
AJMS_480_23.pdf
AJMS_480_23.pdfAJMS_480_23.pdf
AJMS_480_23.pdf
Β 
MT102 Π›Π΅ΠΊΡ† 4
MT102 Π›Π΅ΠΊΡ† 4MT102 Π›Π΅ΠΊΡ† 4
MT102 Π›Π΅ΠΊΡ† 4
Β 

More from Philip Schwarz

A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
Β 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Philip Schwarz
Β 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
Philip Schwarz
Β 
Folding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a seriesFolding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a series
Philip Schwarz
Β 
Scala Left Fold Parallelisation - Three Approaches
Scala Left Fold Parallelisation- Three ApproachesScala Left Fold Parallelisation- Three Approaches
Scala Left Fold Parallelisation - Three Approaches
Philip Schwarz
Β 
Tagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also ProgramsTagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also Programs
Philip Schwarz
Β 
Fusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with ViewsFusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with Views
Philip Schwarz
Β 
A sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in ScalaA sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in Scala
Philip Schwarz
Β 
A sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in ScalaA sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in Scala
Philip Schwarz
Β 
A sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in ScalaA sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in Scala
Philip Schwarz
Β 
N-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets CatsN-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets Cats
Philip Schwarz
Β 
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Philip Schwarz
Β 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Philip Schwarz
Β 
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
Philip Schwarz
Β 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Philip Schwarz
Β 
Jordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axiomsJordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axioms
Philip Schwarz
Β 
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
Philip Schwarz
Β 
Defining filter using (a) recursion (b) folding with S, B and I combinators (...
Defining filter using (a) recursion (b) folding with S, B and I combinators (...Defining filter using (a) recursion (b) folding with S, B and I combinators (...
Defining filter using (a) recursion (b) folding with S, B and I combinators (...
Philip Schwarz
Β 
The Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor correctionsThe Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor corrections
Philip Schwarz
Β 
Computer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1bComputer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1b
Philip Schwarz
Β 

More from Philip Schwarz (20)

A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Β 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Β 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
Β 
Folding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a seriesFolding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a series
Β 
Scala Left Fold Parallelisation - Three Approaches
Scala Left Fold Parallelisation- Three ApproachesScala Left Fold Parallelisation- Three Approaches
Scala Left Fold Parallelisation - Three Approaches
Β 
Tagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also ProgramsTagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also Programs
Β 
Fusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with ViewsFusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with Views
Β 
A sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in ScalaA sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in Scala
Β 
A sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in ScalaA sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in Scala
Β 
A sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in ScalaA sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in Scala
Β 
N-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets CatsN-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets Cats
Β 
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Β 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Β 
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
Β 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Β 
Jordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axiomsJordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axioms
Β 
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
Β 
Defining filter using (a) recursion (b) folding with S, B and I combinators (...
Defining filter using (a) recursion (b) folding with S, B and I combinators (...Defining filter using (a) recursion (b) folding with S, B and I combinators (...
Defining filter using (a) recursion (b) folding with S, B and I combinators (...
Β 
The Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor correctionsThe Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor corrections
Β 
Computer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1bComputer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1b
Β 

Recently uploaded

Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
Β 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
Β 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
Globus
Β 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
Cyanic lab
Β 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
Globus
Β 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Globus
Β 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
Β 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
Β 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
Β 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Globus
Β 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
Β 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
Β 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
informapgpstrackings
Β 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
Β 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
Globus
Β 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
e20449
Β 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
Tier1 app
Β 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
Β 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
Globus
Β 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Natan Silnitsky
Β 

Recently uploaded (20)

Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Β 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Β 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
Β 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
Β 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
Β 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Β 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Β 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Β 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Β 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Β 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Β 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Β 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Β 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Β 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
Β 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
Β 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
Β 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Β 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
Β 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Β 

Left and Right Folds - Comparison of a mathematical definition and a programmatic one - Polyglot FP for Fun and Profit - Haskell and Scala

  • 1. Based on definitions from Left and Right Folds Comparison of a mathematical definition and a programmatic one Polyglot FP for Fun and Profit - Haskell and Scala @philip_schwarz slides by https://www.slideshare.net/pjschwarz Sergei Winitzki sergei-winitzki-11a6431 Richard Bird http://www.cs.ox.ac.uk/people/richard.bird/
  • 2. π‘“π‘œπ‘™π‘‘π‘™ ∷ 𝛽 β†’ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘₯ ∢ π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯ π‘₯𝑠 π‘“π‘œπ‘™π‘‘π‘Ÿ ∷ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯ ∢ π‘₯𝑠 = 𝑓 π‘₯ π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠 If I have to write down the definitions of a left fold and a right fold for lists, here is what I write While both definitions are recursive, the left fold is tail recursive, whereas the right fold isn’t. Although I am very familiar with the above definitions, and view them as doing a good job of explaining the two folds, I am always interested in alternative ways of explaining things, and so I have been looking at Sergei Winitzki’s mathematical definitions of left and right folds, in his upcoming book: The Science of Functional Programming (SOFP). Sergei’s definitions of the folds are in the top two rows of the following table Sergei Winitzki Richard Bird @philip_schwarz
  • 3. test1 = TestCase (assertEqual "foldl(+) 0 []" 0 (foldl (+) 0 [])) test2 = TestCase (assertEqual "foldl(+) 0 [1,2,3,4]" 10 (foldl (+) 0 [1,2,3,4])) test3 = TestCase (assertEqual "foldr (+) 0 []" 0 (foldr (+) 0 [])) test4 = TestCase (assertEqual "foldr (+) 0 [1,2,3,4]" 10 (foldr (+) 0 [1,2,3,4])) Left folds and right folds do not necessarily produce the same results. According to the first duality theorem of folding, one case in which the results are the same, is when we fold using the unit and associative operation of a monoid. First duality theorem. Suppose βŠ• is associative with unit 𝑒. Then π‘“π‘œπ‘™π‘‘π‘Ÿ βŠ• 𝑒 π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ βŠ• 𝑒 π‘₯𝑠 For all finite lists π‘₯𝑠. test5 = TestCase (assertEqual "foldl(-) 0 []" 0 (foldl (+) 0 [])) test6 = TestCase (assertEqual "foldl(-) 0 [1,2,3,4]" (- 10) (foldl (-) 0 [1,2,3,4])) test7 = TestCase (assertEqual "foldr (-) 0 []" 0 (foldr (-) 0 [])) test8 = TestCase (assertEqual "foldr (-) 0 [1,2,3,4]" (- 2) (foldr (-) 0 [1,2,3,4])) Folding integers left and right using the (Int,+,0) monoid, for example, produces the same results. But folding integers left and right using subtraction and zero, does not produce the same results, and in fact (Int,-,0) is not a monoid, because subtraction is not associative.
  • 4. 𝑓 = 𝑏; 𝑓 π‘₯ β§Ί 𝑠 = 𝑔(π‘₯, 𝑓(𝑠)) 𝑓 = 𝑏; 𝑓 𝑠 β§Ί [π‘₯] = 𝑔(𝑓 𝑠 , π‘₯) To avoid any confusion (the definitions use the same function name 𝑓), and to align with the definitions on the right, let’s modify Sergei’s definitions by doing some simple renaming. Here are Sergei’s mathematical definitions again, on the right (the β§Ί operator is list concatenation). Notice how neither definition is tail recursive. That is deliberate. As Sergei explained to me: β€œI'd like to avoid putting tail recursion into a mathematical formula, because tail recursion is just a detail of how we implement this function” and β€œThe fact that foldLeft is tail recursive for List is an implementation detail that is specific to the List type. It will be different for other sequence types. I do not want to put the implementation details into the formulas.” 𝑓 β†’ π‘“π‘œπ‘™π‘‘π‘™ 𝑔 β†’ 𝑓 𝑏 β†’ 𝑒 π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯ β§Ί 𝑠 = 𝑓(π‘₯, π‘“π‘œπ‘™π‘‘π‘Ÿ(𝑠)) π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ 𝑠 β§Ί [π‘₯] = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑠 , π‘₯) 𝑓 β†’ π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑔 β†’ 𝑓 𝑏 β†’ 𝑒 π‘“π‘œπ‘™π‘‘π‘™ ∷ 𝛽 β†’ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘₯ ∢ π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯ π‘₯𝑠 π‘“π‘œπ‘™π‘‘π‘Ÿ ∷ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯ ∢ π‘₯𝑠 = 𝑓 π‘₯ π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠 𝑓 = 𝑏; 𝑓 π‘₯ β§Ί 𝑠 = 𝑔(π‘₯, 𝑓(𝑠)) 𝑓 = 𝑏; 𝑓 𝑠 β§Ί [π‘₯] = 𝑔(𝑓 𝑠 , π‘₯)
  • 5. π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [ ] = 𝑒 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯ β§Ί 𝑠 = 𝑓 π‘₯ (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 𝑠) π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 𝑠 β§Ί [π‘₯] = 𝑓 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 𝑠 π‘₯ π‘“π‘œπ‘™π‘‘π‘™ :: (𝑏 β†’ π‘Ž β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘Žπ‘  = 𝑓 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 (𝑖𝑛𝑖𝑑 π‘Žπ‘ ) (π‘™π‘Žπ‘ π‘‘ π‘Žπ‘ ) π‘“π‘œπ‘™π‘‘π‘Ÿ :: (π‘Ž β†’ 𝑏 β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘Žπ‘  = 𝑓 β„Žπ‘’π‘Žπ‘‘ π‘Žπ‘  π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 (π‘‘π‘Žπ‘–π‘™ π‘Žπ‘ ) π‘“π‘œπ‘™π‘‘π‘™ :: (𝑏 β†’ π‘Ž β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘Žπ‘  = 𝑓 𝑏 π‘Ž π‘€β„Žπ‘’π‘Ÿπ‘’ π‘Ž = π‘™π‘Žπ‘ π‘‘ π‘Žπ‘  𝑏 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 (𝑖𝑛𝑖𝑑 π‘Žπ‘ ) π‘“π‘œπ‘™π‘‘π‘Ÿ :: (π‘Ž β†’ 𝑏 β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘Žπ‘  = 𝑓 π‘Ž 𝑏 π‘€β„Žπ‘’π‘Ÿπ‘’ π‘Ž = β„Žπ‘’π‘Žπ‘‘ π‘Žπ‘  𝑏 = π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 (π‘‘π‘Žπ‘–π‘™ π‘Žπ‘ ) π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯ β§Ί 𝑠 = 𝑓(π‘₯, π‘“π‘œπ‘™π‘‘π‘Ÿ(𝑠)) π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ 𝑠 β§Ί [π‘₯] = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑠 , π‘₯) To help us understand the above two definitions, let’s first express them in Haskell, pretending that we are able to use 𝑠 β§Ί [π‘₯] and π‘₯ β§Ί 𝑠 in a pattern match. Now let’s replace 𝑠 β§Ί [π‘₯] and π‘₯ β§Ί 𝑠 with as, and get the functions to extract the 𝑠 and the π‘₯ using the β„Žπ‘’π‘Žπ‘‘, π‘‘π‘Žπ‘–π‘™, π‘™π‘Žπ‘ π‘‘ and 𝑖𝑛𝑖𝑑. Let’s also add type signatures And now let’s make it more obvious that what each fold is doing is taking an π‘Ž from the list, folding the rest of the list into a 𝑏, and then returning the result of calling 𝑓 with π‘Ž and 𝑏.
  • 6. π‘“π‘œπ‘™π‘‘π‘™ :: (𝑏 β†’ π‘Ž β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘Žπ‘  = 𝑓 𝑏 π‘Ž π‘€β„Žπ‘’π‘Ÿπ‘’ π‘Ž = π‘™π‘Žπ‘ π‘‘ π‘Žπ‘  𝑏 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 (𝑖𝑛𝑖𝑑 π‘Žπ‘ ) π‘“π‘œπ‘™π‘‘π‘Ÿ :: (π‘Ž β†’ 𝑏 β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘Žπ‘  = 𝑓 π‘Ž 𝑏 π‘€β„Žπ‘’π‘Ÿπ‘’ π‘Ž = β„Žπ‘’π‘Žπ‘‘ π‘Žπ‘  𝑏 = π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 (π‘‘π‘Žπ‘–π‘™ π‘Žπ‘ ) Since the above two functions are very similar, let’s extract their common logic into a fold function. Let’s call the function that is used to extract an element from the list π‘‘π‘Žπ‘˜π‘’, and the function that is used to extract the rest of the list π‘Ÿπ‘’π‘ π‘‘. π‘“π‘œπ‘™π‘‘ :: (𝑏 β†’ π‘Ž β†’ 𝑏) β†’ ([π‘Ž] β†’ π‘Ž) β†’ ([π‘Ž] β†’ [π‘Ž]) β†’ 𝑏 β†’ [π‘Ž] β†’ 𝑏 π‘“π‘œπ‘™π‘‘ 𝑓 π‘‘π‘Žπ‘˜π‘’ π‘Ÿπ‘’π‘ π‘‘ 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘ 𝑓 π‘‘π‘Žπ‘˜π‘’ π‘Ÿπ‘’π‘ π‘‘ 𝑒 π‘Žπ‘  = 𝑓 𝑏 π‘Ž π‘€β„Žπ‘’π‘Ÿπ‘’ π‘Ž = π‘‘π‘Žπ‘˜π‘’ π‘Žπ‘  𝑏 = π‘“π‘œπ‘™π‘‘ 𝑓 π‘‘π‘Žπ‘˜π‘’ π‘Ÿπ‘’π‘ π‘‘ 𝑒 (π‘Ÿπ‘’π‘ π‘‘ π‘Žπ‘ ) We can now define left and right folds in terms of π‘“π‘œπ‘™π‘‘. π‘“π‘œπ‘™π‘‘π‘™ :: (𝑏 β†’ π‘Ž β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 = π‘“π‘œπ‘™π‘‘ 𝑓 π‘™π‘Žπ‘ π‘‘ 𝑖𝑛𝑖𝑑 π‘“π‘œπ‘™π‘‘π‘Ÿ :: (π‘Ž β†’ 𝑏 β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 = π‘“π‘œπ‘™π‘‘ 𝑓𝑙𝑖𝑝 𝑓 β„Žπ‘’π‘Žπ‘‘ π‘‘π‘Žπ‘–π‘™ 𝑓𝑙𝑖𝑝 :: (π‘Ž β†’ 𝑏 β†’ 𝑐) β†’ 𝑏 β†’ π‘Ž β†’ 𝑐 𝑓𝑙𝑖𝑝 𝑓 π‘₯ 𝑦 = 𝑓 𝑦 π‘₯ The slightly perplexing thing is that while a left fold applies 𝑓 to list elements starting with the β„Žπ‘’π‘Žπ‘‘ of the list and proceeding from left to right, the above π‘“π‘œπ‘™π‘‘π‘™ function achieves that by navigating through list elements from right to left. Third duality theorem. For all finite lists π‘₯𝑠, π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓𝑙𝑖𝑝 𝑓 𝑒 (π‘Ÿπ‘’π‘£π‘’π‘Ÿπ‘ π‘’ π‘₯𝑠) π’˜π’‰π’†π’“π’† 𝑓𝑙𝑖𝑝 𝑓 π‘₯ 𝑦 = 𝑓 𝑦 π‘₯ The fact that we can define π‘“π‘œπ‘™π‘‘π‘™ and π‘“π‘œπ‘™π‘‘π‘Ÿ in terms of π‘“π‘œπ‘™π‘‘, as we do above, seems related to the third duality theorem of folding. Instead of our π‘“π‘œπ‘™π‘‘π‘™ function being passed the reverse of the list passed to π‘“π‘œπ‘™π‘‘π‘Ÿ, it processes the list with π‘™π‘Žπ‘ π‘‘ and 𝑖𝑛𝑖𝑑, rather than with β„Žπ‘’π‘Žπ‘‘ and π‘‘π‘Žπ‘–π‘™. @philip_schwarz
  • 7. To summarise what we did to help understand SOFP’s mathematical definitions of left and right fold: we turned them into code and expressed them in terms of a common function π‘“π‘œπ‘™π‘‘ that uses a π‘‘π‘Žπ‘˜π‘’ function to extract an element from the list being folded, and a π‘Ÿπ‘’π‘ π‘‘ function to extract the rest of the list. π‘“π‘œπ‘™π‘‘ :: (𝑏 β†’ π‘Ž β†’ 𝑏) β†’ ([π‘Ž] β†’ π‘Ž) β†’ ([π‘Ž] β†’ [π‘Ž]) β†’ 𝑏 β†’ [π‘Ž] β†’ 𝑏 π‘“π‘œπ‘™π‘‘ 𝑓 π‘‘π‘Žπ‘˜π‘’ π‘Ÿπ‘’π‘ π‘‘ 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘ 𝑓 π‘‘π‘Žπ‘˜π‘’ π‘Ÿπ‘’π‘ π‘‘ 𝑒 π‘Žπ‘  = 𝑓 𝑏 π‘Ž π‘€β„Žπ‘’π‘Ÿπ‘’ π‘Ž = π‘‘π‘Žπ‘˜π‘’ π‘Žπ‘  𝑏 = π‘“π‘œπ‘™π‘‘ 𝑓 π‘‘π‘Žπ‘˜π‘’ π‘Ÿπ‘’π‘ π‘‘ 𝑒 (π‘Ÿπ‘’π‘ π‘‘ π‘Žπ‘ ) π‘“π‘œπ‘™π‘‘π‘™ :: (𝑏 β†’ π‘Ž β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 = π‘“π‘œπ‘™π‘‘ 𝑓 π‘™π‘Žπ‘ π‘‘ 𝑖𝑛𝑖𝑑 π‘“π‘œπ‘™π‘‘π‘Ÿ :: (π‘Ž β†’ 𝑏 β†’ 𝑏) β†’ 𝑏 β†’[π‘Ž] β†’ 𝑏 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 = π‘“π‘œπ‘™π‘‘ 𝑓𝑙𝑖𝑝 𝑓 β„Žπ‘’π‘Žπ‘‘ π‘‘π‘Žπ‘–π‘™ π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯ β§Ί 𝑠 = 𝑓(π‘₯, π‘“π‘œπ‘™π‘‘π‘Ÿ(𝑠)) π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ 𝑠 β§Ί [π‘₯] = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑠 , π‘₯) π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘Žπ‘  = 𝑓(β„Žπ‘’π‘Žπ‘‘(π‘Žπ‘ ), π‘“π‘œπ‘™π‘‘π‘Ÿ(π‘‘π‘Žπ‘–π‘™(π‘Žπ‘ ))) π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ π‘Žπ‘  = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑖𝑛𝑖𝑑(π‘Žπ‘ ) , π‘™π‘Žπ‘ π‘‘(π‘Žπ‘ )) Let’s feed one aspect of the above back into Sergei’s definitions. Let’s temporarily rewrite them by replacing 𝑠 β§Ί [π‘₯] and π‘₯ β§Ί 𝑠 with as, and getting the definitions to extract the 𝑠 and the π‘₯ using the functions β„Žπ‘’π‘Žπ‘‘, π‘‘π‘Žπ‘–π‘™, π‘™π‘Žπ‘ π‘‘ and 𝑖𝑛𝑖𝑑. Notice how the flipping of 𝑓 done by the π‘“π‘œπ‘™π‘‘π‘Ÿ function above, is reflected, in the π‘“π‘œπ‘™π‘‘π‘Ÿ function below, in the fact that its 𝑓 takes an π‘Ž and a 𝑏, rather than a 𝑏 and an π‘Ž.
  • 8. Another thing we can do to understand SOFP’s definitions of left and right folds, is to see how they work when applied to a sample list, e.g. [π‘₯0, π‘₯1, π‘₯2, π‘₯3], when we run them manually. In the next slide we first do this for the following definitions π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ 𝑠 β§Ί [π‘₯] = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑠 , π‘₯) π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯ β§Ί 𝑠 = 𝑓(π‘₯, π‘“π‘œπ‘™π‘‘π‘Ÿ(𝑠)) π‘“π‘œπ‘™π‘‘π‘™ ∷ 𝛽 β†’ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘₯ ∢ π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯ π‘₯𝑠 π‘“π‘œπ‘™π‘‘π‘Ÿ ∷ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯ ∢ π‘₯𝑠 = 𝑓 π‘₯ π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠 In the slide after that, we do it for SOFP’s definitions.
  • 9. ∢ / π‘₯0 ∢ / π‘₯1 ∢ / π‘₯2 ∢ / π‘₯3 𝑓 / 𝑓 π‘₯3 / 𝑓 π‘₯2 / 𝑓 π‘₯1 / 𝑒 π‘₯0 𝑓 / π‘₯0 𝑓 / π‘₯1 𝑓 / π‘₯2 𝑓 / π‘₯3 𝑒 π‘₯0: (π‘₯1: π‘₯2: π‘₯3: ) 𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 π‘₯3 var π‘Žπ‘π‘ = 𝑒 foreach(π‘₯ in π‘₯s) π‘Žπ‘π‘ = 𝑓(π‘Žπ‘π‘, π‘₯) return π‘Žπ‘π‘ π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘₯𝑠 π‘₯𝑠 = [π‘₯0, π‘₯1, π‘₯2, π‘₯3] π‘“π‘œπ‘™π‘‘π‘Ÿ ∷ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯: π‘₯𝑠 = 𝑓 π‘₯ π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠 π‘“π‘œπ‘™π‘‘π‘™ ∷ 𝛽 β†’ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘₯: π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯ π‘₯𝑠 π‘Ÿπ‘’π‘π‘™π‘Žπ‘π‘’: ∢ π‘€π‘–π‘‘β„Ž 𝑓 π‘€π‘–π‘‘β„Ž 𝑒 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯0, π‘₯1, π‘₯2, π‘₯3] 𝑓 π‘₯0 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯1, π‘₯2, π‘₯3] 𝑓 π‘₯0 (𝑓 π‘₯1 (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯2, π‘₯3])) 𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯3]))) 𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (𝑓 π‘₯3 (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [ ])))) 𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (𝑓 π‘₯3 𝑒))) 𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (𝑓 π‘₯3 𝑒))) π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 [π‘₯0, π‘₯1, π‘₯2, π‘₯3] π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯0 [π‘₯1, π‘₯2, π‘₯3] π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 [π‘₯2, π‘₯3] π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 [π‘₯3] π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 π‘₯3 [ ] 𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 π‘₯3
  • 10. ∢ / π‘₯0 ∢ / π‘₯1 ∢ / π‘₯2 ∢ / π‘₯3 𝑓 / 𝑓 π‘₯3 / 𝑓 π‘₯2 / 𝑓 π‘₯1 / 𝑒 π‘₯0 𝑓 / π‘₯0 𝑓 / π‘₯1 𝑓 / π‘₯2 𝑓 / π‘₯3 𝑒 π‘₯0: (π‘₯1: π‘₯2: π‘₯3: ) 𝑓(𝑓 𝑓 𝑓 𝑒, π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3) π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯𝑠 π‘“π‘œπ‘™π‘‘π‘™ π‘₯𝑠 π‘₯𝑠 = [π‘₯0, π‘₯1, π‘₯2, π‘₯3] 𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, 𝑓(π‘₯3, 𝑒)))) π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ 𝑠 β§Ί [π‘₯] = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑠 , π‘₯) π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯ β§Ί 𝑠 = 𝑓(π‘₯, π‘“π‘œπ‘™π‘‘π‘Ÿ(𝑠)) π‘“π‘œπ‘™π‘‘π‘™ π‘₯0, π‘₯1, π‘₯2, π‘₯3 , 𝑓 π‘“π‘œπ‘™π‘‘π‘™ π‘₯0, π‘₯1, π‘₯2 , π‘₯3 𝑓(𝑓(π‘“π‘œπ‘™π‘‘π‘™ [π‘₯0, π‘₯1] , π‘₯2), π‘₯3) 𝑓 𝑓 𝑓 π‘“π‘œπ‘™π‘‘π‘™ π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3 𝑓 𝑓 𝑓 𝑓 π‘“π‘œπ‘™π‘‘π‘™ [ ] , π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3 𝑓 𝑓 𝑓 𝑓 𝑒, π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3 π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯0, π‘₯1, π‘₯2, π‘₯3]) 𝑓(π‘₯0, π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯1, π‘₯2, π‘₯3])) 𝑓(π‘₯0, 𝑓(π‘₯1, π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯2, π‘₯3]))) 𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯3])))) 𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, 𝑓(π‘₯3, π‘“π‘œπ‘™π‘‘π‘Ÿ([]))))) 𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, 𝑓(π‘₯3, 𝑒))))
  • 11. π‘“π‘œπ‘™π‘‘π‘™ ∷ 𝛽 β†’ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 π‘₯: π‘₯𝑠 = π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯ π‘₯𝑠 π‘“π‘œπ‘™π‘‘π‘™ = 𝑒; π‘“π‘œπ‘™π‘‘π‘™ 𝑠 β§Ί [π‘₯] = 𝑓(π‘“π‘œπ‘™π‘‘π‘™ 𝑠 , π‘₯) ∢ / π‘₯0 ∢ / π‘₯1 ∢ / π‘₯2 ∢ / π‘₯3 π‘₯0: (π‘₯1: π‘₯2: π‘₯3: ) π‘₯𝑠 = [π‘₯0, π‘₯1, π‘₯2, π‘₯3] 𝑓 / 𝑓 π‘₯3 / 𝑓 π‘₯2 / 𝑓 π‘₯1 / 𝑒 π‘₯0 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑒 [π‘₯0, π‘₯1, π‘₯2, π‘₯3] π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑒 π‘₯0 [π‘₯1, π‘₯2, π‘₯3] π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 [π‘₯2, π‘₯3] π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 [π‘₯3] π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 π‘₯3 [ ] 𝑓 𝑓 𝑓 𝑓 𝑒 π‘₯0 π‘₯1 π‘₯2 π‘₯3 π‘“π‘œπ‘™π‘‘π‘™ π‘₯0, π‘₯1, π‘₯2, π‘₯3 , 𝑓 π‘“π‘œπ‘™π‘‘π‘™ π‘₯0, π‘₯1, π‘₯2 , π‘₯3 𝑓(𝑓(π‘“π‘œπ‘™π‘‘π‘™ [π‘₯0, π‘₯1] , π‘₯2), π‘₯3) 𝑓 𝑓 𝑓 π‘“π‘œπ‘™π‘‘π‘™ π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3 𝑓 𝑓 𝑓 𝑓 π‘“π‘œπ‘™π‘‘π‘™ [ ] , π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3 𝑓 𝑓 𝑓 𝑓 𝑒, π‘₯0 , π‘₯1 , π‘₯2 , π‘₯3 Now let’s compare the results for both definitions of π‘“π‘œπ‘™π‘‘π‘™. The results are the same. @philip_schwarz
  • 12. 𝑓 / π‘₯0 𝑓 / π‘₯1 𝑓 / π‘₯2 𝑓 / π‘₯3 𝑒 π‘“π‘œπ‘™π‘‘π‘Ÿ ∷ 𝛼 β†’ 𝛽 β†’ 𝛽 β†’ 𝛽 β†’ 𝛼 β†’ 𝛽 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 = 𝑒 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯: π‘₯𝑠 = 𝑓 π‘₯ π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 π‘₯𝑠 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯0, π‘₯1, π‘₯2, π‘₯3] 𝑓 π‘₯0 π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯1, π‘₯2, π‘₯3] 𝑓 π‘₯0 (𝑓 π‘₯1 (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯2, π‘₯3])) 𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [π‘₯3]))) 𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (𝑓 π‘₯3 (π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓 𝑒 [ ])))) 𝑓 π‘₯0 (𝑓 π‘₯1 (𝑓 π‘₯2 (𝑓 π‘₯3 𝑒))) π‘“π‘œπ‘™π‘‘π‘Ÿ = 𝑒; π‘“π‘œπ‘™π‘‘π‘Ÿ π‘₯ β§Ί 𝑠 = 𝑓(π‘₯, π‘“π‘œπ‘™π‘‘π‘Ÿ(𝑠)) π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯0, π‘₯1, π‘₯2, π‘₯3]) 𝑓(π‘₯0, π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯1, π‘₯2, π‘₯3])) 𝑓(π‘₯0, 𝑓(π‘₯1, π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯2, π‘₯3]))) 𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, π‘“π‘œπ‘™π‘‘π‘Ÿ([π‘₯3])))) 𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, 𝑓(π‘₯3, π‘“π‘œπ‘™π‘‘π‘Ÿ([]))))) 𝑓(π‘₯0, 𝑓(π‘₯1, 𝑓(π‘₯2, 𝑓(π‘₯3, 𝑒)))) ∢ / π‘₯0 ∢ / π‘₯1 ∢ / π‘₯2 ∢ / π‘₯3 π‘₯0: (π‘₯1: π‘₯2: π‘₯3: ) π‘₯𝑠 = [π‘₯0, π‘₯1, π‘₯2, π‘₯3] And now let’s compare the results for both definitions of π‘“π‘œπ‘™π‘‘π‘Ÿ. Again, the results are the same.
  • 13. The way π‘“π‘œπ‘™π‘‘π‘Ÿ applies 𝑓 to π‘₯, 𝑦, z is by associating to the right. The way π‘“π‘œπ‘™π‘‘π‘™ does it is by associating to the right. Thinking of 𝑓 as an infix operator can help to grasp this. π‘“π‘œπ‘™π‘‘π‘Ÿ 𝑓(π‘₯, 𝑓(𝑦, 𝑧)) π‘₯ βŠ• 𝑦 βŠ• 𝑧 π‘“π‘œπ‘™π‘‘π‘™ 𝑓 𝑓 π‘₯, 𝑦 , 𝑧 (π‘₯ βŠ• 𝑦) βŠ• 𝑧 π‘“π‘œπ‘™π‘‘π‘Ÿ βŠ• 𝑒 π‘₯, 𝑦, z = π‘₯ βŠ• (𝑦 βŠ• 𝑧 βŠ• 𝑒 ) π‘“π‘œπ‘™π‘‘π‘Ÿ (+) 0 [1,2,3] = 1 + (2 + (3 + 0)) = 6 π‘“π‘œπ‘™π‘‘π‘™ (+) 0 [1,2,3] = ((0 + 1) + 2) + 3 = 6 π‘“π‘œπ‘™π‘‘π‘Ÿ βˆ’ 0 1,2,3 = 1 βˆ’ (2 βˆ’ (3 βˆ’ 0)) = 2 π‘“π‘œπ‘™π‘‘π‘™ βˆ’ 0 1,2,3 = ((0 βˆ’ 1) βˆ’ 2) βˆ’ 3 = βˆ’6 βŠ• / π‘₯ βŠ• / 𝑦 βŠ• / 𝑧 𝑒 βŠ• / βŠ• 𝑧 / βŠ• 𝑦 / 𝑒 π‘₯ π‘“π‘œπ‘™π‘‘π‘™ βŠ• 𝑒 π‘₯, 𝑦, 𝑧 = ((𝑒 βŠ• π‘₯) βŠ• 𝑦) βŠ• 𝑧 Addition is associative, so associating to the left and to the right yields the same result. But subtraction isn’t associative, so associating to the left yields a result that is different to the one yielded when associating to the right.
  • 14. We have seen that Sergei’s definitions of left and right folds make perfect sense. Not only are they simple and succinct, they are also free of implementation details like tail recursion. That’s all. I hope you found this slide deck useful. By the way, in case you are interested, see below for a whole series of slide decks dedicated to folding.