Implementing "unlawful monads" would be equal to giving someone a float and telling them "you can use this like a rational number from math". And in fact it might work for the longest time - until it doesn't (think rounding-errors and similar) and then the confusion will be big.
With monads it's the same, but potentially even worse, because it's rather easy to test float addition behavior, but for certain monads that can be much harder.
Haskell has a library called monad-validate that I think is a great example for both what the monad laws are important for, and how it's important that one understand their reasons, instead of just following advice literally on every possible situation.
Just as yo want to break addition commutativity so you can approximate real numbers, there are times when you want something to behave like a monad, but not follow its laws.
It gives a lot of theoretical background, but if you read the article here and already know the Optional-type and then you can skip it and go directly to "A Real World Example".
thanks! this link should have been the main news; so much easier to think of 'unit' as object constructor, and of 'bind' as flatmap; the article also does a great job of explaining the purpose of the monad laws.
Monads should satisfy the "monad laws": left identity, right identity, and associativity.
IIRC, Haskell relies on two out of the three, but I don't remember which two. But if you write a "monad" that doesn't satisfy them (even though it has the right function signatures), then you're going to get bogus results.
Functor, monoid and monad laws allow for undefined evaluation order, lazy evaluation, parallell execution and same results for same parameters. But only if the laws holds can such be guaranteed when using certain abstractions. Associativity being one obvious caveat that might break abstraction over collections, while using divide & conquer mechanics such as function currying.