我写了很多代码,如下所示:
popStack groupTail
|> andThen
(\( parentGroup, parentTail ) ->
addChild currentGroup sibling
|> andThen
(\updatedParent ->
case sibling of
SingleExercise _ ->
workHelp siblingIndent (updatedParent :: parentTail)
WorkGroup _ _ ->
workHelp siblingIndent (sibling :: (updatedParent :: parentTail))
)
)
感觉很像所有嵌套andThen
调用的回调地狱,我想知道是否有惯用的方法来使用不同类型的函数应用程序来避免所有嵌套。
答案 0 :(得分:3)
@Reactormonk提供了一个有用的链接,但Elm
不是Haskell
。否则,我们可以使用Maybe monad
提供的do-notation
和句法糖。类似的东西:
do
(parentGroup, parentTail) <- popStack groupTail
updatedParent <- addChild currentGroup sibling
case sibling of
SingleExercise _ ->
workHelp siblingIndent (updatedParent : parentTail)
WorkGroup _ _ ->
workHelp siblingIndent (sibling : (updatedParent : parentTail))
但在Elm
中,我最终将逻辑转移到单独的函数中:
let
workHelpToSibling sibling ( parentTail, updatedParent ) =
case sibling of
SingleExercise ->
workHelp siblingIndent (updatedParent :: parentTail)
WorkGroup ->
workHelp siblingIndent (sibling :: (updatedParent :: parentTail))
addChildTo currentGroup sibling ( parentGroup, parentTail ) =
addChild currentGroup sibling
|> Maybe.map (\updatedParent -> ( parentTail, updatedParent ))
in
popStack groupTail
|> andThen (addChildTo currentGroup sibling)
|> andThen (workHelpToSibling sibling)
由于您可以在更高级别访问currentGroup
和sibling
,因此可以通过减少函数的arity(而不仅仅是这个)来重构此代码。
我只是想指出最小化缩进程度的想法,这确实提醒了回调地狱。