在没有明确检查成功的情况下链接数据库插入

Eco*_*ium 1 monads haskell persistent

我试图弄清楚case在将记录插入数据库时是否有办法避免大量语句.

我目前的代码类似于:

mt1 <- runDb $ do
        muid <- insertUnique user
        case muid of 
            Just uid -> do
                let t1 = Table1 {..., user = uid} 
                maid  <- insertUnique t1
                case maid of
                    Just aid -> do 
                        mo <- getBy $ UniqueField "somevalue" 
                        case mo of
                            Just (Entity oid o) -> do
                                mcid <- insertUnique Table2 {..., oid = oid} 
                                case mcid of
                                    Just cid -> do 
                                        mfid <- insertUnique Table3 {..., cid = cid} 
                                        case mfid of 
                                            Just fid -> Just t1 -- original t1 that was created at the top of the chain
                                            Nothing  -> Nothing
                                    Nothing  -> Nothing 
                            Nothing -> Nothing 
                    Nothing -> Nothing 
                Nothing -> Nothing
            Nothing  -> Nothing
Run Code Online (Sandbox Code Playgroud)

首先,我在编译代码时遇到了问题,但我没有尝试调试代码,而是想知道是否有更好的方法来执行此操作.

在概念层面,我想做类似下面的事情,其中​​所有Maybe值都自动解包,以便在后续调用中使用.如果有任何意义,我们打了一个Nothing,我只是想回来Nothing.整个代码将在一个事务中运行,因此如果我们Nothing在中间运行,则事务将回滚

runDb $ do
    uid <- insertUnique user
    let t1 = Table1 {..., user = uid} -- uid is unwrapped to just the value 
    aid  <- insertUnique t1
    o <- getBy $ UniqueField "somevalue"
    cid <- insertUnique Table2 {..., oid = oid}
    fid <- insertUnique Table3 {..., cid = cid} 
    Just t1 
Run Code Online (Sandbox Code Playgroud)

我是Haskell的初学者所以我只对Monads有了肤浅的理解(我可以使用简单的那些)但是当它在runDbPersistent之类的内容中使用它时,我不知道如何把它们放在一起.

关于我如何简单逻辑的任何建议,所以我不会最终检查每一步的失败?

更新:根据迈克尔的回答,我做了类似的事情,并在使用时自动解开maybes.

mt1 <- runDb $ runMaybeT $ do 
           uid <- MaybeT $ insertUnique user
           ... 
case mt1 of
    Just t -> return t
    Nothing -> lift $ left ... 
Run Code Online (Sandbox Code Playgroud)

谢谢!

Mic*_*man 6

像这样的标准方法是MaybeTmonad变换器.像下面这样的东西可能会起作用:

runMaybeT $ do
    uid <- MaybeT $ insertUnique user
    ...
Run Code Online (Sandbox Code Playgroud)