“A mathematician, like a painter or a poet, is a maker of patterns. If his patterns are more permanent than theirs, it is because they are made with ideas.” — G.H. Hardy, A Mathematician’s Apology Sometimes, logical accuracy is not possible because of intrinsic complexity of the data, in practical programming. Data Abstraction is a very useful tool which helps us in creating a simplified representation of the data. In order to achieve this, we create ‘ ’, these containers only and only contain our data and do nothing else, we don’t provide them properties or methods like in OOP. Containers We take a value and put it inside our container, the container will keep our value safe, while we pass it on through our beautiful functional logic. We’ll only take that value out when we need that urgently. In this way our container will have only two tasks: Keeping the value inside itself. . Giving us the value back, only when we require it Also, never mutate the value inside them. And these containers are not something new, we’ve been using them since we started JavaScripting, only knowing them now will make us more powerful programmer. When we do functional programming, these containers are very powerful, as they contribute to the base of our functional constructs, and help us with common techniques like Pure Functional Error Handling and Asynchronous Actions . (and many more things) Before we go on in deep about these containers, we are going to talk about a special type of containers called Functors. So, What are Functors? Functors are the containers that can be used with ‘map’ function. Before we create our own containers, let’s look at some common containers we’ve been using since our childhood. Arrays Arrays are the most common containers we use in our daily programming, instead of containing just one value they contain several. They are the simplest of all Data Abstractions, yet so powerful. Let’s work with them, const arr = [ 8, 10, 23, 35, 54 ]; and we can get the values out of them like const b = a[1]; Now, if you promise to use only these operations on the arrays, I’ll promise you that these arrays will be your friends forever. Never modify the original array like, arr.push(45) ❌ or arr[1] = 45 ❌ But you can always use them to create new ones, const arr2 = [ ...arr, 38, 52 ] or const even = filter(x => x%2 === 0, arr) We never ever apply any methods on arrays that may change the value inside them, we just create the arrays or get the values out, that’s it. While the Java guys will say with doing this I’ve rendered my array useless, but I’ll say, “No, I have just created my array so powerful than you can ever imagine”. And yes Array is a Functor. A Functor is a container which can be upon by a Unary function. mapped When I say mapped upon, I mean that this container can be treated with a special function(say ) which applies any unary function to every content of this container and returns a container with the resulting values as its contents. fmap or map This truck is a functor In case of arrays, the special function is simply called the function. map The Map Function Not this Map Map function in arrays takes an array and applies a particular function to all of its elements one by one and returns another array. [1,2,3,4].map(multiplyBy2) //=> [2,4,6,8] or map(multiplyBy2, [1,2,3,4]) //=> [2,4,6,8] where multiplyBy2 = x => x * 2 and map = (fn, arr) => arr.map(fn) Since, we’ll always be getting another array from the map, we can always map it again to create a chain of array transformations. [1,2,3]. (x => x * 3). (x => x * 2). (x => x / 6) map map map A Map function is more than an iterator function, , when our value is inside a container we cannot just directly apply a function on it and expect the value to be changed. For example, remember const a = [1, 2, 3] String(a) = ‘[1 ,2, 3]’ and not [‘1’, ‘2’, ‘3’] A map function gives a function access to the contents of the container. map(String, [1, 2, 3]) = [‘1’, ‘2’, ‘3’] Also, a map function never changes the container, instead it just act upon its contents. Keeping the container retained. A map will not change the type of the container but it can change the type of its contents. The type of the contents may change, and we can see that from the type definition of the map function. map :: (a -> b) -> [a] -> [b] or fmap :: (a -> b) -> F a -> F b Here, and can be of same type or different type. a b Now, if you squint your eyes really hard, you’ll see that map function is taking a function from and returning a function from a -> b Fa -> Fb Here, means any unary function that takes and returns like a -> b a b multiplyBy2(3) = 6 // is a -> b as 3 -> 6 and means any unary function that takes a Container with inside and returns a Container with inside. Fa -> Fb a b multiplyArrBy2([1]) = [2] // is Fa -> Fb as [1] -> [2], F is [] To understand how we are using these types read this, _When a Javascript Developer starts to explore the deepest secrets of the Functional Programming, he often finds these…_hackernoon.com Function Type Signatures in Javascript Now how is our map function is changing to let’s see this, multiplyBy2 multiplyArrBy2 For now our function which used to act upon integers, now because of will act upon array of integers. In a way, our map function promoted or our function so that it can act on our containers or arrays in this case. multiplyBy2 map lifted We occasionally lift our functions so that they can act upon our data inside our containers. (Because normal functions can’t) We use partially applied map function whenever possible because then we can use it to create another functions or we can use this with function, and when there’s an extreme urgency of data, we’ll use our normal map function. compose Why should we use partially applied functions? _Providing function with fewer arguments than it expects is called Partial Application of functions._hackernoon.com Partial Application of Functions we know that we use containers to hold our values and their only purpose is to hold them. We also know about which are special containers on which we can do operation. We know how a map function is used on Arrays, also we’ve met our first Container and a Functor, Array which we use frequently in our daily programming. Before going any further, Functors map Now, let’s meet our second container which is also a functor. This container was with us all along from the starting of our functional adventures. Functions All Functions are functors too and hence are also containers. How Functions are containers? Okay, containers contain data, but our functions clearly contain logic, so how can functions be containers. : a function, when called, returns a value. So in a way, it is containing our value, the only difference is that the value is dynamically computed. Well if you think it through aFunction(45) // => 90 So aFunction gives the value 90, when it is passed 45 Think of them as arrays of infinite number of values and if you want a particular value from those, you need to call the function with the particular argument or arguments. Functions are arrays with Infinite Values So, Functions are containers like arrays? Yes, just like arrays give value when an index is passed, functions give result when an argument is passed. const a = [ 8, 10, 23, 35, 54 ] const f = z => z * 2 a[1] = 10f(2) = 4 Only our arrays are weaker as they only give results for ranged integers only as index, but our functions can take any type of arguments because there’s no limit to them, they can also take other functions as arguments too. Functions are containers with infinite no. of values. Since they are Functors they have a too? map Yes, it is defined like this const fnMap = (f, mappingFn) => (x => f(mappingFn(x))) Just like the function takes the array, applies the function to the contents and returns the array. Similarly, takes a function, applies another function to its result and returns the function, in a way it’s combining two functions map fnMap s_uch that the result of one function is the argument of the second function._ Hmm, okay let’s use this const multiplyBy6 = fnMap(multiplyBy2, multiplyBy3) This looks familiar, we’ve seen this before. It is our function. Compose So, our functions too have a function and if we are mapping one function to another, we are kind of fusing those two functions. A map over function is called a function. map Compose tl;dr Let’s say we have a function . multiplyBy2 Before taking out the value from it or say calling it, we mapped it with . multiplyBy3 So all the values inside are multiplied by 3. multiplyBy2 Now, whenever we call with let’s say the value we get will be . multiplyBy2 x x * 3 * 2 Perhaps, now this will be clearer, const fnMap = (f, mappingFn) => (x => f(mappingFn(x))) Functions are like arrays, a type of data abstraction. Only functions compute the data according to our requirements . Or we can say that Arrays are like functions they just give away their result instantly when we use ‘[]’ on them. We can bend our mind in any way to understand this, it’s all true. We only have to remember one thing that our value is only valuable, if its inside a container, either a function, or an array or a container we have created only then we can break down complex structures in our code, possibly arising due to complexity in data, to simpler ones. From now on, I need you remember this thing, in functional programming . Always wrap it inside a container. never use your data naked Now, this article is too long to discuss more about Functors. But I promise, we’ll continue this in another one. Written with 💖.