gpt4 book ai didi

haskell - 如何在另一个 monad 中使用 Maybe monad?

转载 作者:行者123 更新时间:2023-12-02 10:54:53 25 4
gpt4 key购买 nike

我有这个代码(在 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 ()

我想删除嵌套的 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。如何使用 Maybe monad 评估嵌套的 do block ? (我也接受删除嵌套案例的不同重构。)

更新:下面是同一问题的通用版本,尽管是人为的:

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!"

最佳答案

好的,通过您的通用示例,我可以使用 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 block 中执行所有计算,最后检查是否为 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"

使用 liftIOAlternative 类型类的另一个版本:

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 ()

但是使用许多电梯操作并不是很优雅。

关于haskell - 如何在另一个 monad 中使用 Maybe monad?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20293006/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com