Laziness is not always good
From HaskellWiki
Generally, since Haskell is a non-strict language, one 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 theMonoid
()
mempty = () mappend _ _ = ()
These functions are least strict, but have a subtle problem: They do not generally satisfy the monoid laws.
Remind you:mempty
mappend
forall a. mappend mempty a = a forall a. mappend a mempty = a
mappend mempty undefined = undefined
mappend mempty undefined = mempty
Is this academic nitpicking or practically relevant?
I think it is the latter one, because aMonoid
that monoid laws can be applied in every case.
A programmer expects that every occurence ofmappend mempty a
a
You might even create an optimizer rule doing this.
The above implementation ofmappend
and this gets lost when the optimization is applied.
The solution to this to define
mempty = () mappend () () = () force :: () -> () force _ = ()
and write
mappend (force a) (force b)
mappend a b
If you find that example too academic, you can choose any other data type with one constructor instead.
See also
- Haskell-Cafe on Laws and partial values
- Maintaining laziness
