У меня есть этот код (внутри happstack, но может быть просто монадой ввода-вывода):
accountHandler conn = do
sessionId <- optional $ readCookieValue "sessionId"
case sessionId of
Nothing -> seeOther ("/" :: String) $ toResponse ()
Just s -> do
result <- loggedInUserId conn s
case result of
Just userId -> seeOther ("/account/" ++ unUserId userId) $ toResponse ()
Nothing -> seeOther ("/" :: String) $ toResponse ()
Я хочу удалить вложенные операторы case и написать что-то вроде:
accountHandler conn = do
let action = do
sessionId <- optional $ readCookieValue "sessionId"
userId <- loggedInUserId conn sessionId
return $ seeOther ("/account/" ++ userId)
maybe (seeOther ("/" :: String)) id action $ toResponse ()
... но userId оказывается типом Maybe String
, а не просто String
. Как я могу оценить вложенный блок do
с помощью монады may? (Я бы также согласился на другой рефакторинг, удаляющий вложенные случаи.)
ОБНОВЛЕНИЕ: Ниже приведена общая, хотя и надуманная версия той же проблемы:
module Main where
getAnswer expected = do
l <- getLine
if l == expected
then return $ Just l
else return $ Nothing
main = do
a <- getAnswer "a"
case a of
Nothing -> putStrLn "nope"
Just x -> do
b <- getAnswer x
case b of
Nothing -> putStrLn "nope"
Just _ -> putStrLn "correct!"