
Apologies for being a bit blunt, but can't this problem be solved by introducing a LazyStateT in addition to StateT? This follows the pattern of ST (default is strict, we also have Control.Monad.ST.Lazy). Cheers, Simon On 23 November 2005 09:59, Udo Stenzel wrote:
Hello Yitzchak,
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.
as Iavor already pointed out, theres the fine difference between being string in some implementation detail (the pair of state and result) or in the state itself, which I missed.
I was thinking of the state component, and I maintain that it should be strict. Rationale: if the state is some primitive type, you want it strict anyway. If it isn't, the strictness doesn't cost much anyway. If it's still wrong, wrapping in a constructor helps.
Your problem however is the strict match against a pair you don't even know is there. Indeed, a strict match against a single constructor datatype is probably always pointless. So it's really a bug in the library, after all.
Here is an example. How would you fix this by wrapping something in a constructor?
You can't, since you don't have access to the offending pair.
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
...but this is probably broken anyway. After (repeatM randomItem) presumably the state (the RandomGen) is _|_, but the type of createItems would suggest it is still usable. I wouldn't do that. Other than that it's a bit hard to see what you're trying to accomplish here.
Udo.