
Yitzchak Gale wrote:
You're right, it is not in the docs. I don't think anyone would have planned it that way. StateT is strict only because there happens to be a line in a do-expression that looks like: (a, s') <- runStateT m s The tuple pattern-match causes the strictness. That appears accidental, so it seems to be just an honest bug.
I agree that this is an accident, but the bug is in lazy State, for three reasons: - Being strict in the (result,state) pair does not for the evaluation of either result or state. Not being strict could only ever be useful for a following action that made no use of either state or result, and I have a hard time imagining why you'd ever want to write such a beast, let alone in monadic style. In fact, an unboxed tuple would be even better. - Assuming that the State monad is lazy in the tuple, and you need to be strict in the state component, you are hosed. No amount of 'seq' will help you. On the other hand, were it strict and you needed it to be lazy, you could achieve that by manually boxing the data involved. - (>>=) should also be head strict in the state component. Again, if this is wrong, you can repair it. If laziness turns out wrong, you can't. Moreover, for most data types that you want to build lazily, especially lists, head strictness doesn't make a difference, as long as the tail is lazily evaluated. For data where you need strictness, such as integers or tuples of them, having strictness available make all the difference. I'd be fine with laziness being configurable, of course, but if it isn't, I want strict state. Come to think of it, it's probably just a bad idea that _|_ and (_|_,_|_) are different things. -Udo -- The Seventh Commandments for Technicians: Work thou not on energized equipment, for if thou dost, thy fellow workers will surely buy beers for thy widow and console her in other ways.