What happens to you if you break the monad laws?

The monad laws are simply additional rules that instances are expected to follow, beyond what can be expressed in the type system. Insofar as Monad expresses a programming pattern, the laws are part of that pattern. Such laws apply to other type classes as well: Monoid has very similar rules to Monad, and it’s generally expected that instances of Eq will follow the rules expected for an equality relation, among other examples.

Because these laws are in some sense “part of” the type class, it should be reasonable for other code to expect they will hold, and act accordingly. Misbehaving instances may thus violate assumptions made by client code’s logic, resulting in bugs, the blame for which is properly placed at the instance, not the code using it.

In short, “breaking the monad laws” should generally be read as “writing buggy code”.


I’ll illustrate this point with an example involving another type class, modified from one given by Daniel Fischer on the haskell-cafe mailing list. It is (hopefully) well known that the standard libraries include some misbehaving instances, namely Eq and Ord for floating point types. The misbehavior occurs, as you might guess, when NaN is involved. Consider the following data structure:

> let x = fromList  [0, -1, 0/0, -5, -6, -3] :: Set Float

Where 0/0 produces a NaN, which violates the assumptions about Ord instances made by Data.Set.Set. Does this Set contain 0?

> member 0 x
True

Yes, of course it does, it’s right there in plain sight! Now, we insert a value into the Set:

> let x' = insert (0/0) x

This Set still contains 0, right? We didn’t remove anything, after all.

> member 0 x'
False

oh. Oh, dear.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)