nus-cs2030 / 2021-s1

27 stars 48 forks source link

Functors vs monads #518

Open LapisRaider opened 4 years ago

LapisRaider commented 4 years ago

Hello!

I just want to check what's the difference between functors and monads and how to tell if a class is one.

From what I read up on, Functor is just an immutable generic box and it needs to follow 2 laws where it has a constructor and has a map method to change the value and return a new box with said value.

While for monads is basically functor but with a flatmap function too?

So does that mean a monad can basically be a functor but a functor may not be a monad if that's the case?

Please do let me know if I got any information wrong or if there's anything else I'm missing. I'm really confuse on the differences between monads and functors.

Thank you!

sushmit98 commented 4 years ago

Hi!

Based on what I've read up on as well, your understanding of functor is correct. It must have the capability to convert the payload from type A to type B using a .map() method. Based on the lecture notes, the two laws it has to satisfy are identity and associativity.

Identity just means that if the function in the .map() method, say func, is an identity function like x -> x, then it should not change the functor. And associativity means that if func is a composition of two functions g⋅h, then the resulting functor should be the same as calling f with hand then with g.

A monad is something that can take in a function, and return a monad itself using a .flatMap() method. To be more specific, this .flatMap() method should take in a value from the 'box' and return a boxed value with the function applied. A monad needs to have a unit operator like .of() to wrap an object into the monad. There are three further laws that monads have to satisfy - left identity, right identity and associativity.

Left identity means that Box.of(x).flatMap(f).equals.(f(x)) should return true. Right identity means that monad.flatMap(x -> Monad.of(x)).equals(monad) should also return true. Assiciativity means that if we have a box (monad) and a chain of functions that operate on it, then it shouldn't matter how we nest the flatMappings of those functions.

You can check out this website for a better and more in-depth explanation: https://miklos-martin.github.io/learn/fp/2016/03/10/monad-laws-for-regular-developers.html#:~:text=The%20laws,identity%2C%20right%20identity%20and%20associativity.

Definitely, a functor is not always a monad. I think a monad usually has to be a functor because it does convert a boxed value into a different type (a nested box), and it does seem to satisfy the laws of functors too. But would be good if someone could shed more light on this.

rehmmann commented 4 years ago

Thankss!!