30

JS Monday 09 – Understanding Functors

 5 years ago
source link: https://www.tuicool.com/articles/hit/jYRZJ3e
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

When you’re digging deep into a language or a paradigm, you’ll inevitably find some concepts that are hard to understand.

Not every developer have an academic background so same concepts, terms or abstractions are hard to understand and adopt.

One concept that’s certainly hard to understand is: what is a Functor ?

Well, I bet you’re already using functors every day without knowing it!

A Functor is a map between two categories.

Real world example? The awesome .map method from our first article, can be applied on arrays… which are functors !

As written in the Haskell Data.Functor specification, Functors uniforms action over a parameterized type, generalizing the map function on lists.

Let’s throw away all that abstract things and let’s see in practice how to adopt Functors!

Functors in practice

q6nYfuN.png!web

As you can see in the example above, an array is functor because we can map over it.

We can apply a function to each element and get back the same structure, respecting the Functor Laws :

  1. Functors must preserve identity morphisms

    When performing the mapping operation, if the values in the functor are mapped to themselves, the result will be an unmodified functor.
  2. Functors preserve composition of morphisms

    If two sequential mapping operations are performed one after the other using two functions, the result should be the same as a single mapping operation with one function that is equivalent to applying the first function to the result of the second.
2M3uiyB.png!webymiIfmB.png!web

So as you can see, we can apply double and add5 functions to our array using the map method. Chaining multiple map methods will always produce the same output, thanks to the Functor Laws!

Now you may ask: “ as far as I know,  .map can be used only on arrays, so only arrays are functors! ” … wrong ! You can create a Functor out of mostly any value, that’s why is so important to understand what Functors are!

Let’s implement a Functor from zero, respecting the Functor Laws:

NjeIFfr.png!webEbumMf6.png!web

Great, we just defined an algebra that will be our starting point!

Now, in order to make it look like a real Functor, we need to make it mappable, always respecting the Functor Laws.

3EbEveV.png!web2eyquuV.png!web

Great! We just created our first mappable Functor! Let’s test it:

Zzeea2u.png!webyqmu6jM.png!web

That’s awesome! Let’s see if it respects the Functor Laws:

  1. Does it return an unmodified functor? Yes!
  2. Are we able to map over and over it, always respecting the first law? Yes!

Functors and Objects

Object can be Functors too! And it’s easiest than you think:

AVRBviU.png!webe6vq2qN.png!web

Ok, that may not be so easy if you’re not familiar with immutability. So, I’ll rewrite the same function using loops to help you understand:

QjmiAbI.png!webVVfaquN.png!web

Great! So now that we have our Functor, let’s try it out!

nemiYfJ.png!webziM7Bva.png!web

Isn’t that awesome?

You just used classes! Is there a way to make it pure?

As you may know, classes in JavaScript are just functions. Given the fact that classes contains an internal state, they are not pure functions .

So is there a way to build a “pure” Functor?

FFVV7jN.png!webUFZNZni.png!web

Holy guacamole that’s sooooo easy! Let’s test it against a number!

UNjaQf6.png!webQjYnQ3J.png!web

Amazing! As you may already know, the following expressions are equivalent:

VniyAvN.png!webMBvyMnY.png!web

Why should I care about Functors?

Functors are a key topic in both mathematics and computer science.

Without understanding Functors, we won’t be able to understand Monads and other amazing things.

Functors adds some kind of safety in our program, just think how predictable our output can be.

They are also an awesome abstraction which enables you to work on a certain way on any datatype. Remember undefined and null ? Functors makes them safe:

YbamqeV.png!webiaAbMff.png!web

So as you can read, we can only apply certain functions when a value is known (so not undefined or null ).

Conclusion

So, in few words, a Functor is a thing we can map over. If you’re familiar with category theory , you may have noticed that a Functor maps from category to category .

A Functor which maps from category back to the same category is called Endofunctor (for instance, a monad is an endofunctor ).

I really hope that Functors aren’t a mystery anymore!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK