用"IO"代码中的"Maybe"值重构"阶梯"

bet*_*eta 7 monads haskell maybe io-monad

以下函数f尝试Int使用IO (Maybe Int)函数两次读取两次,但在成功读取一次后执行"短路"执行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
Run Code Online (Sandbox Code Playgroud)

有没有一种很好的方法来重构这段代码?如果我将它扩展到三次尝试,这将变得非常毛茸茸......

(我的思维过程:看到这个"staircasing"告诉我,也许我应该使用Monad的情况Maybe,但由于这是已经在IO单子,我将不得不使用MaybeT(),但我只需要?一个readInt来成功,所以Maybemonad在第一次Nothing出错的行为在这里是错误的...)

Lee*_*Lee 8

您可以使用MaybeTMonadPlus实例使用msum:

f :: MaybeT IO Int
f = msum [readInt, readInt, readInt]
Run Code Online (Sandbox Code Playgroud)