如何处理多级缩进? [英] How do I deal with many levels of indentation?
问题描述
我正在编写一个具有非常复杂的逻辑循环的脚本:
I am writing a script that has a very logically complicated loop:
main = do
inFH <- openFile "..." ReadMode
outFH <- openFile "..." WriteMode
forM myList $ item ->
...
if ...
then ...
else do
...
case ... of
Nothing -> ...
Just x -> do
...
...
代码很快向右飞,所以我想把它分成几部分,例如使用 where
子句.问题是,其中许多 ...
包含对 inFH
和 outFH
两个句柄的读/写语句,并使用 where
语句将使这两个名称脱离上下文.每次使用 where
语句时,我都必须发送这两个变量.
The code soon flies to the right, so I was thinking breaking it into pieces, using for example where
clauses. The problem is, many of these ...
contain reading/writing statements to the two handles inFH
and outFH
, and using a where
statement will render those two names out of context. I would have to send in these two variables everytime I use a where
statement.
有没有更好的方法来处理这个问题?
Is there a better way of dealing with this?
推荐答案
在很多情况下,这些深度嵌套的缩进是深度嵌套错误检查的结果.如果你是这样,你应该研究 MaybeT
和它的老大哥 ExceptT
.这些提供了一种干净的方法来将出现问题时我们做什么"代码与假设一切正常我们做什么"代码分开.在你的例子中,我可能会写:
In many cases, these deeply-nested indentations are the result of deeply-nested error checking. If that's so for you, you should look into MaybeT
and its big brother ExceptT
. These offer a clean way to separate the "what do we do when something went wrong" code from the "what do we do assuming everything goes right" code. In your example, I might write:
data CustomError = IfCheckFailed | MaybeCheckFailed
main = handleErrors <=< runExceptT $ do
inFH <- liftIO $ openFile ...
outFH <- liftIO $ openFile ...
forM myList $ item -> do
when (...) (throwError IfCheckFailed)
...
x <- liftMaybe MaybeCheckFailed ...
...
liftMaybe :: MonadError e m => e -> Maybe a -> m a
liftMaybe err = maybe (throwError err) return
handleErrors :: Either CustomError a -> IO a
handleErrors (Left err) = case err of
IfCheckFailed -> ...
MaybeCheckFailed -> ...
handleErrors (Right success) = return success
注意我们仍然在forM
循环处增加缩进;但其他检查在 main
中内嵌"完成,并且在 handleErrors
中以相同的缩进级别处理.
Notice that we still increase indentation at the forM
loop; but the other checks are done "in-line" in main
, and are handled all at the same indentation level in handleErrors
.
这篇关于如何处理多级缩进?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!