Maybe处理技巧

判断多个Maybe都不为Nothing

case of 嵌套

1
2
3
4
5
6
7
8
9
processValues :: Maybe String -> Maybe String -> Maybe String -> IO ()
processValues ma mb mc = do
case ma of
Nothing -> responseFail "ma 为空"
Just a -> case mb of
Nothing -> responseFail "mb 为空"
Just b -> case mc of
Nothing -> responseFail "mc 为空"
Just c -> responseSuccess "成功"

模式匹配

将多个Maybe组成元组用于模式匹配

1
2
3
4
5
6
7
processValues :: Maybe String -> Maybe String -> Maybe String -> IO ()
processValues ma mb mc =
case (ma, mb, mc) of
(Nothing, _, _) -> responseFail "ma 为空"
(_, Nothing, _) -> responseFail "mb 为空"
(_, _, Nothing) -> responseFail "mc 为空"
(Just a, Just b, Just c) -> responseSuccess "成功"

traverse

1
2
3
4
5
6
7
processValues :: Maybe String -> Maybe String -> Maybe String -> IO ()
processValues ma mb mc = do
let values = [ma, mb, mc]
let result = traverse id values -- 遍历每个 Maybe 值,保持原有的结构
case result of
Nothing -> responseFail "有空值"
Just _ -> responseSuccess "成功"

MaybeT

1
2
3
4
5
6
7
8
processValues :: Maybe String -> Maybe String -> Maybe String -> IO ()
processValues ma mb mc = do
runMaybeT $ do
a <- MaybeT (maybe (responseFail "ma为空" >> return Nothing) (return . Just) ma)
b <- MaybeT (maybe (responseFail "mb为空" >> return Nothing) (return . Just) mb)
c <- MaybeT (maybe (responseFail "mc为空" >> return Nothing) (return . Just) mc)
liftIO $ responseSuccess "成功"
return ()

下面这句将Maybe String转为IO (Maybe String),如果为Nothing将会打印提示

1
maybe (responseFail "ma为空" >> return Nothing) (return . Just) ma)

MaybeT包裹IO (Maybe String)使得遇到Nothing后短路