Given the following:

> (liftM2 fromMaybe) (ioError $ userError "OOPS") (return $ Just "ok")

ghci gives me

*** Exception: user error (OOPS)

Of course, fromMaybe is working correctly:

> (liftM2 fromMaybe) (return $ "not me") (return $ Just "ok")
"ok"

But it seems that the IO operation is being carried out and then discarded:

> (liftM2 fromMaybe) (putStrLn "computing.." >> "discarded") (return $ Just "ok")
computing..
"ok"

Why is this happening? Is there any way to make the IO monad lazier?

Specifically, given value :: IO (Maybe a) what's a (clean, concise) way to say

result <- (liftM2 fromMaybe) err value

and have it unpack result or throw an IOError accordingly?

Edit
Report