import Control.Monad.State.Lazy
type Queue a = [a]
push :: a -> State (Queue a) ()
push x = state (\xs -> ((),xs++[x]))
pop :: State (Queue a) a
pop = state (\(x:xs) -> (x,xs))
queueManip :: State (Queue Int) Int
queueManip =
do
mapM_ push [1..]
a <- pop
return a
main :: IO()
main = do
let (a,_) = runState queueManip []
print a
Shouldn't the mapM_ be lazy ? Besides for implementing a queue shouldn't the complexity be O(1)?
Because the append (++) itself is lazy ...
What if I'm evil and use
push' :: Int -> State (Queue Int) ()
push' 1052602983 = state $ \_ -> ((), []) -- "Muarhar!"
push' x = state $ \xs -> ((),xs++[x])
Then mapM push' [1..] should clearly render the state as [1052602983, 1052602984 ..]. It would be wrong for pop to yield 1. But mapM can't possibly know this, without first evaluating a billion other numbers. Actually pushing them to the state is irrelevant here, and it also doesn't matter that push could be completely lazy: mapM at least has to give it a chance to check any given number, before handing on the monadic program flow.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With