RE: Bug in Control.Monad.State

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.

On Wed, Nov 23, 2005 at 10:47:02AM -0000, Simon Marlow wrote:
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).
That would be great. Except that I would prefer StrictState, with laziness the default. ST is from the IO family of monads, so one expects strictness. MTL monads are usually pure, so the default should be laziness like everywhere else in Haskell. Many of the programs I have written in the past few years would break if State were to become strict. But in any case, there is still a bug to fix. State and StateT are currently straddling both sides of the fence; State is lazy, and StateT is strict. Regards, Yitz
participants (2)
-
Simon Marlow
-
Yitzchak Gale