
Hi Udo,
Lack of laziness is also a serious problem that a user cannot avoid. In my case, I have to completely rewrite StateT, otherwise it is totally unusable. This is definitely a bug.
I disagree. If an operation is lazy, there is absolutely nothing you as a user can to to change that.
Right. Well, you can rewrite the library, or you can restructure your entire app, but neither of those are very good options.
If an operation is too strict... you can always wrap the offending data in another constructor.
I have seen this claim several times, but I am not yet convinced. In my case, the unwanted strictness is coming from the bind method of a monad from the standard libraries. I don't see how to get rid of that strictness by wrapping something in a constructor. And even when it is possible to reduce strictness by wrapping something - it means changing the interface of existing functions. In a large application, that could be a major disaster. Here is an example. How would you fix this by wrapping something in a constructor? No restructuring is allowed (this is one function in a large application, so changing the interface of any function could have major consequences), and no rewriting libraries is allowed. You need to construct a random list of items. you do not know in advance how many I will need; that is determined by a stateful calculation as you construct the items. Here is the function; it diverges, unless you rewrite StateT with strictness removed: createItems :: RandomGen g => State g [Item] createItems = liftM catMaybes $ runListT $ flip evalStateT initialState $ runMaybeT $ do item <- liftRandom $ repeatM randomItem updateState item needMoreItems >>= guard return item where liftRandom = lift . lift . lift Regards, Yitz