我有这个代码(在happstack里面,但可能只是IO monad):
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 ()
Run Code Online (Sandbox Code Playgroud)
我想删除嵌套的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 ()
Run Code Online (Sandbox Code Playgroud)
...但是userId最终Maybe String
只是一种而不仅仅是String
.如何do
使用monad来评估嵌套块?(我也会接受一个不同的重构来删除嵌套的案例.)
更新:以下是同一问题的通用但经过设计的版本:
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!"
Run Code Online (Sandbox Code Playgroud)
好的,通过你的通用例子,我可以做些什么Control¸Monad.Transformers
.这允许您创建一组monad.你可以在这里查看:http:
//hackage.haskell.org/package/transformers-0.3.0.0/docs/Control-Monad-Trans-Maybe.html你可以将MaybeT应用于所有类型IO (Maybe a)
,然后进行所有计算在内部do块中,然后在最后检查Nothing.
module Main where
import Control.Monad.Trans.Maybe
getAnswer expected = MaybeT $ do
l <- getLine
if l == expected
then return $ Just l
else return $ Nothing
main = do
y <- runMaybeT $ do a <- getAnswer "a"
b <- getAnswer a
return b
case y of Nothing -> putStrLn "failure"
(Just _) -> putStrLn "correct"
Run Code Online (Sandbox Code Playgroud)
使用的另一个版本liftIO
和Alternative
类型类:
module Main where
import Control.Monad.Trans.Maybe
import Control.Monad.IO.Class
import Control.Applicative
getAnswer expected = MaybeT $ do
l <- getLine
if l == expected
then return $ Just l
else return $ Nothing
main = do
_ <- runMaybeT $ do a <- getAnswer "a"
b <- getAnswer a
liftIO $ putStrLn "correct"
<|> do liftIO $ putStrLn "failure"
return ()
Run Code Online (Sandbox Code Playgroud)
但是使用许多升降机操作并不是很优雅.
归档时间: |
|
查看次数: |
1856 次 |
最近记录: |