Collections
Types of collections
The List Collection
In Python, a list is defined as [1, 2, 3]
. In Monty, it's the exact same syntax. However, every element of the list must be of the same type. So unlike in Python, you cannot have a list such as [1, 2, "apples"]
.
The Set Collection
Like with lists, sets must contain all the same type: Set(1, 2, 3)
Working with Collections
Changing the contents
Suppose you have the following Python code:
The map
function takes in the collection, then a function to change the contents. This is how you change values of a collection in functional languages.
So let's rewrite it:
Remember, we can write functions inline using the syntax (x): x + 1
Accumulating results
Suppose you have the following Python code:
Fairly simple, it adds all the results from inputs
up into result
. In Monty, this code becomes a problem. Remember, we can't change result
after we define it.
Let's reimplement the above Python code to not change result
:
OK that should be fine in Monty, since nothing changes after being defined.
"But it's clunky! I like the first example waaaaaaaaaay more!"
I agree with you. Let's create a function called fold
that will help us with this. I want something generalized to take in a function, which combines all of the values together. It will also need an accumulator parameter
Now with this function, we can clean up the immutable Python code with:
Much nicer! And we can easily change what that function does.
In Monty, lists have a foldl
method out of the box, so rewriting this in Monty:
The Maybe Collection
Functors
"Whoa whoa whoa, what's a Functor?! Why'd you have to drop that bomb on me!"
Stay calm! A Functor is just something that you can map
over.
"Whew ok, that's not so bad"
For the examples given... for loops seem simpler than using a map, don't you agree?
Trees
Say you have this code in Python:
How would you increment all the values, as we did with the list example?
"Let's see... looks like we'll need a recursive function, something like"
"That wasn't so bad."
Sorry, I actually have a tree that has any number of branches. Can you rewrite add1
for that please?
"OK, I'll just need to change add1 a bit..."
Before going on with this charade, let's talk about doing this in Monty instead of Python. This is a Monty book after all.
Let's rewrite BTree
:
OK, add1
can be implemented as:
It's almost identical to the Python code, and it has the same problem as the Python code. Now, remember that a Functor is something you can map
over. What if we could map
over this tree? Then we could use the exact same code to increment all the values as with the list:
OK now make inputs a list again.
"OK that's fine, none of the code for results
will change`
But wait, how does BTree
magically become a Functor? Sit tight until the chapter on type classes and you'll find out!
Foldables
A Foldable is something you can call foldl
on, such as lists.
Now, going back to the accumulating list example. What if we wanted to accumulate the contents of a tree in Python? Like for the add1
example for Functors above, it would require some fancy logic.
Remember what foldl
does. It goes over a collection, and gathers all the contents into a single value.
Guess what? A Tree is foldable! So we use the exact same code as for lists: