[Haskell-cafe] Laziness question

Nicolas Pouillard nicolas.pouillard at gmail.com
Sun Aug 1 10:29:55 EDT 2010

On Sun, 1 Aug 2010 10:53:24 +0200, Stefan Holdermans <stefan at vectorfabrics.com> wrote:
> Nicolas,
> > I would deeply in favor of renaming seq to unsafeSeq, and introduce a
> > type class to reintroduce seq in a disciplined way.
> There is a well-documented [1] trade-off here:  Often, calls to seq are introduced late in a developing cycle; typically after you have discovered a space leak and figured out how to resolve it.  Then you introduce a call to seq somewhere deep in a call chain.  If seq were a class method, you would know have to work your way upward in the call chain to update all type signatures you had written there.  Clearly, this is quite tedious.  And then, almost just as often, you find out that actually you did not quite figure out how to resolve the space leak, because it's still there.  So, you remove your freshly introduced call to seq and, indeed, work your way to the call chain again to remove all now superfluous class constraints from the type signatures. (By the way, this is typically the sort of task, IDEs with refactoring support excel at, but these are unfortunately not ubiquitous for Haskell yet.)

Only in the case where the type of the value being forced is not known,
otherwise the class constraint get silently discarded.

> More importantly, the type-class approach is flawed [2].  It assumes that all seq-related constraints can be "read off from type variables", which is in fact not the case.

Indeed they give some account to the type class approach but not enough IMHO.
Sure forcing functions is a tricky business and having a generic instance for
functions is clearly not the solution (as they explain it with foldl vs foldl''').

However I absolutely do not buy their argument using as example a function
f :: Eval (a -> Int) => (a -> Int) -> (a -> Int) -> Int. They consider as
an issue the fact that the type does not tell us on which argument seq is
used. I think it is fine we may want a more precise type for it to get more
properties out of it but it is not flawed.
As much as we don't know where (==) is used given a function of type
∀ a. Eq a => [a] -> [a].

Actually my point is that if we do not use any polymorphic primitive to
implement a family of seq functions then it cannot be flawed. Indeed
if you read type classes as a way to implicitly pass and pick functions
then it cannot add troubles.

Finally maybe we can simply forbidden the forcing of function (as we do with
Eq). The few cases where it does matter will rescue to unsafeSeqFunction.


Nicolas Pouillard

More information about the Haskell-Cafe mailing list