Laziness is not always good
Generally, since Haskell is a non-strict language, you should try to make a function least strict. This is in many cases the best semantics and the most efficient implementation. However, here is an important exception from the rule:Consider the
mempty = () mappend _ _ = ()
These functions are least strict, but have a subtle problem: They do not generally satisfy the monoid laws.Remind you:
forall a. mappend mempty a = a forall a. mappend a mempty = a
Is this academic nitpicking or practically relevant?I think it is the latter one, because a
that monoid laws can be applied in every case.A programmer expects that every occurence of
You might even create an optimizer rule doing this.The above implementation of
and this gets lost when the optimization is applied.
The solution of this issue is to define
mempty = () mappend () () = () force :: () -> () force _ = ()
mappend (force a) (force b)
If you find that example too academic, you can choose any other data type with one constructor instead.