Is there any recommend guidelines when to use strictness in Haskell ?
For example, I was looking on the tagsoup library. They have one of their data structure defined like this:
data Tag str
= TagOpen str [Attribute str]
| TagClose str
| TagText str
| TagComment str
| TagWarning str
| TagPosition !Row !Column
type Row = Int
type Column = Int
So on what factor exactly do they decide that TagPosition
should be strict ? Are there any recommend guidelines for this ?
For simple, unstructured datatypes such as Int
or Double
, turning them into strict fields is often a good default. That makes their space consumption very predictable (and constant). While it's possible that performance degrades due to performing unnecessary computations, this is, in general unlikely. For example, keeping track of a position is usually extremely simple and inexpensive, so there's nothing to be afraid of in terms of performance, and having predictable space behaviour is far more important.
An additional advantages of making simple types strict is that they can often be unpacked, i.e., stored directly within the constructor instead of via an additional indirection (there are pragmas or compiler flags for it). For small types, this usually is an advantage.
For structured datatypes such as lists or trees, the situation is far more complicated. A simple !
will rarely help here, because it only forces to WHNF. An evaluated list or tree can also easily be more costly in terms of space than an unevaluated thunk. Nevertheless, it sometimes makes sense to make such data strict as well. In such cases, you usually would wrap the constructor using a function (a so-called smart constructor) that establishes strictness invariants by calling deepseq
in appropriate places.
来源:https://stackoverflow.com/questions/21279207/haskell-guidelines-for-using-strictness