我有以下代碼示例:
data Smth = A | B
data MyError = MkMyError
data MyState = MkMyState
run :: [Smth] -> Either MyError (Maybe Integer)
run param =
evalState
( foldM
( \acc a -> do
res <- go a
case res of
Right (Just _) -> undefined -- I want to break here when Right value is Just
_ -> return (acc >> res)
)
(Right Nothing)
param
)
MkMyState
where
go :: Smth -> State MyState (Either MyError (Maybe Integer))
go = undefined
我有Smth一個按順序處理的串列,它們根據Statemonad 中的狀態和Smth值處理結果。
run我想打破go結果MyError(左值Either)。這適用于使用>>運算子的代碼片段。
但是,我還希望有可能在go函式導致時打破折疊Right (Just _)(該行有注釋)。
題
當我得到值時如何打破以下回圈Just?我想在兩種情況下打破回圈:
- 在錯誤的情況下 -
go導致Left價值 - 在價值的情況下
Just-go產生Right (Just _)價值。Maybe這是monad 和運算子的某種翻轉行為>>。我不想中斷Nothing,但是Just。
這怎么可能組成?
uj5u.com熱心網友回復:
我是否正確,您只想處理Smths ,只要go繼續回傳,并在第一次呼叫導致或不運行任何更多呼叫Right Nothing時停止?goLeft _Right (Just _)go
如果是這樣,我認為您foldM在這里沒有任何意義。如果出現錯誤 or Just,您想立即停止,但foldM只是在錯誤 or 之后繼續處理Smths Just。acc >> res確保 fold 最終回傳第一個錯誤的值,但您仍然處理所有Smths (或者如果輸入串列是無限的,則永遠運行)。
相反,你想要類似的東西process:
run :: [Smth] -> Either MyError (Maybe Integer)
run param = evalState (process param) MkMyState
where
process :: [Smth] -> State MyState (Either MyError (Maybe Integer))
process (a:as) = do
res <- go a
case res of
Right Nothing -> process as
_ -> return res -- stop on Left _ or Right (Just _)
process [] = return $ Right Nothing
go :: Smth -> State MyState (Either MyError (Maybe Integer))
go = undefined
如果你真的想寫成process折疊,你可以,雖然它只是 a foldr,而不是 a foldM:
process :: [Smth] -> State MyState (Either MyError (Maybe Integer))
process = foldr step (return $ Right Nothing)
where step a acc = do
res <- go a
case res of
Right Nothing -> acc
_ -> return res
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/427240.html
