How to format nested continuations nicely
I am writing a lot of code like below:
popStack groupTail
|> andThen
(\( parentGroup, parentTail ) ->
addChild currentGroup sibling
|> andThen
(\updatedParent ->
case sibling of
SingleExercise _ ->
workHelp siblingIndent (updatedParent :: parentTail)
WorkGroup _ _ ->
workHelp siblingIndent (sibling :: (updatedParent :: parentTail))
)
)
It is very similar to a callback addon with all nested calls andThen
, and I was wondering if there are idiomatic ways to use different types of applications to avoid all nesting.
source to share
@Reactormonk provided a helpful link, but Elm
not Haskell
. Otherwise, we could have used the Maybe monad
syntactic sugar provided do-notation
. Something like:
do
(parentGroup, parentTail) <- popStack groupTail
updatedParent <- addChild currentGroup sibling
case sibling of
SingleExercise _ ->
workHelp siblingIndent (updatedParent : parentTail)
WorkGroup _ _ ->
workHelp siblingIndent (sibling : (updatedParent : parentTail))
But in Elm
I would include the move logic in separate functions:
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)
Since you have currentGroup
and sibling
are available at a higher level, this code can be refactored to reduce the arity of functions (and not only that).
I just wanted to point out the idea of โโminimizing the padding level, which really looks like backwards hell.
source to share