Let me just explain to you what functional programming is at a high level and I'll get a little bit into the monad. Maybe that will help you understand.

IF you can compress all your javascript into one line of code or as close to it as much as possible then you are absolutely doing functional programming.

That is essentially what functional programming is, how to program so everything goes on one line. You can think of it as expression based programming, or how to compress your entire program into a single expression!

Now, when you see multiline functional code, what's actually happening is that the programmer is giving parts of his expression a name and placing it on another line so that the code is more readable or the programmer could be generalizing logic in the expression for reuse in other places. Example:

addOneTime8PlusTwoMinusThreeTimes300 = (x) => (x + 1 * 8) + 2 - 3 * 300

is made into

addOneTimes8 = function(x) => x + 1 * 8
plusTwoMinusThreeTimes300 = function(x) => 2 - 3 * 300

addOneTime8PlusTwoMinusThreeTimes300 = (x) => plusTwoMinusThreeTimes300(addOneTimes8(x))

That's it! Turns out that doing this type of organization is EXACTLY the same as doing procedural programming with one extra property! Keeping everything immutable! So if you program in javascript and you keep everything immutable you are doing the exact same thing as compressing all your code onto a single line!

Now that being said there's a lot of this going on in functional programming:

addOneTime8PlusTwoMinusThreeTimes300 = function(x) => Times300(MinusThree(PlusTwo(Times8(addOne(x)))))

and to make things more easier to read people have special syntax to write it like this:

addOneTime8PlusTwoMinusThreeTimes300 = function(x) => ( addOne | Times8 | PlusTwo | MinusThree )(x)

The above is literally the same thing as operator overloading you just define the operator to be:

f | y = function(x) => f(y(x))

and you use it as such:

( f | a | b | x )(x)

like bash kinda.

This type of thing is called function composition!

A monad is just a special type of composition Not only do I want to compose all the functions but at each step of the composition I want to do an extra thing! So let's say I want to log the output

So I define

f | y = (x) => {
result = y(x)
print(result)
return f(result)
}

Then when I compose:

( f | a | b | x )(x)

It will print out each intermediary value along the pipeline!

That is essentially one type of monad. A monad is a way to compose functions such that they do an extra thing! And this intuition probably takes you 85% of the way there on how to use monads in haskell. Monads in haskell just have some extra rules but the intuition is 100% the same thing.

Now you will note that I cheated for f | y. I wrote the code on multiple lines! That is exactly what "sequential" code is!

It is the fundamental property of reality that is at odds with functional programming. Haskell is trying to get rid code that requires you to write things on multiple lines! It is trying to abstract all of that away with a bunch of crazy abstractions so all your code can fit beautifully onto a single line! It is in fact impossible to write the multi line code I wrote above in haskell. What haskell does is present to you the IO monad as an API so you print things through composition and you never have to write "sequential" lines of code.

Turns out when you do single line coding a whole class of errors disappears and your code is also far more modular. It's hard to convince you of the benefits with just words. If you want to know more, you have to walk the path, I can only show you the way.

One more thing. When code is written this way the compiler can do much more tricks with it. Because state is immutable the compiler can execute code in a different order to achieve the same result as your intention. You don't have to often think about this when programming in haskell but it does allow you to do certain tricks.