The following function f attempts to read an Int twice by using an IO (Maybe Int) function twice, but “short-circuits” execution after successfully reading one Int:
readInt :: IO (Maybe Int)
f :: IO (Maybe Int)
f = do
  n1 <- readInt
  case n1 of
      Just n' -> return (Just n')
      Nothing -> do
        n2 <- readInt
        case n2 of
              Just n' -> return (Just n')
              Nothing -> return Nothing
Is there a good way to refactor this code? This would get very hairy if I extended it to three attempts…
(My thought process: Seeing this “staircasing” tells me that maybe I should be using the Monad instance of Maybe, but since this is already in the IO monad, I would then have to use MaybeT(?). However, I only need one of the readInt to succeed, so the Maybe monad's behaviour of erroring out on the first Nothing would be wrong here...)
You can use MaybeT and the MonadPlus instance to use msum:
f :: MaybeT IO Int
f = msum [readInt, readInt, readInt]
                        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