如何很好地格式化嵌套的延续

时间:2017-07-23 22:21:45

标签: elm

我写了很多代码,如下所示:

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调用的回调地狱,我想知道是否有惯用的方法来使用不同类型的函数应用程序来避免所有嵌套。

1 个答案:

答案 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)

由于您可以在更高级别访问currentGroupsibling,因此可以通过减少函数的arity(而不仅仅是这个)来重构此代码。

我只是想指出最小化缩进程度的想法,这确实提醒了回调地狱。