Input:
headingsDecoder : String -> String -> BackendTask FatalError (Entry Data)
headingsDecoder slug rawBody =
let
findThis : Result String (List Block) -> BackendTask FatalError (Entry Data)
findThis =
Debug.todo "REPLACE"
in
rawBody
|> Markdown.Parser.parse
|> Result.mapError (\_ -> "Markdown parsing error")
|> findThis
Available Elm functions (you must use some of these but not all of them will be needed or useful for the solution):
- gatherHeadings : List Block -> List ( Block.HeadingLevel, List Inline )
- nameAndTopLevel : String -> List ( Block.HeadingLevel, List Block.Inline ) -> Result String (Entry Data)
- FatalError.fromString : String -> FatalError
- BackendTask.mapError : (error -> errorMapped) -> BackendTask error value -> BackendTask errorMapped value
- BackendTask.fromResult : Result error value -> BackendTask error value
- BackendTask.fail : error -> BackendTask error a
- Result.map : (a -> value) -> Result x a -> Result x value
- Result.andThen : (a -> Result x b) -> Result x a -> Result x b
- Result.mapError : (x -> y) -> Result x a -> Result y a
- Result.withDefault : a -> Result x a -> a
- Result.toMaybe : Result x a -> Maybe a
- Result.fromMaybe : x -> Maybe a -> Result x a
We can add a type annotation in our let binding to make our target type that we are trying to fill in explicit.
headingsDecoder : String -> String -> BackendTask FatalError (Entry Data)
headingsDecoder slug rawBody =
let
findThis : Result String (List Block) -> BackendTask FatalError (Entry Data)
findThis =
Debug.todo "REPLACE"
in
rawBody
|> Markdown.Parser.parse
|> Result.mapError (\_ -> "Markdown parsing error")
|> findThis
Step 2:
Result.andThen ALMOST gives us the desired type (Result String (List Block) -> BackendTask FatalError (Entry Data)), but it takes a function of type List Block -> Result FatalError (Entry Data) instead of List Block -> BackendTask FatalError (Entry Data). As an intermediary step, we create a let binding with a type annotation, and add a Debug.todo to fill in that would turn it into the desired type.
headingsDecoder : String -> String -> BackendTask FatalError (Entry Data)
headingsDecoder slug rawBody =
let
processListBlock : List Block -> Result FatalError (Entry Data)
processListBlock =
Debug.todo "REPLACE"
findThis : Result String (List Block) -> BackendTask FatalError (Entry Data)
findThis =
Result.andThen processListBlock
in
rawBody
|> Markdown.Parser.parse
|> Result.mapError (\_ -> "Markdown parsing error")
|> findThis
Step 3:
Now we can fill in the processListBlock helper function:
headingsDecoder : String -> String -> BackendTask FatalError (Entry Data)
headingsDecoder slug rawBody =
let
processListBlock : List Block -> Result FatalError (Entry Data)
processListBlock listBlock =
listBlock
|> gatherHeadings
|> nameAndTopLevel slug
findThis : Result String (List Block) -> BackendTask FatalError (Entry Data)
findThis =
Result.andThen processListBlock
in
rawBody
|> Markdown.Parser.parse
|> Result.mapError (\_ -> "Markdown parsing error")
|> findThis
Step 4:
Now, we need to convert the Result FatalError (Entry Data) from findThis into a BackendTask FatalError (Entry Data) using BackendTask.fromResult.
headingsDecoder : String -> String -> BackendTask FatalError (Entry Data)
headingsDecoder slug rawBody =
let
processListBlock : List Block -> Result FatalError (Entry Data)
processListBlock listBlock =
listBlock
|> gatherHeadings
|> nameAndTopLevel slug
findThis : Result String (List Block) -> BackendTask FatalError (Entry Data)
findThis result =
result
|> Result.andThen processListBlock
|> BackendTask.fromResult
in
rawBody
|> Markdown.Parser.parse
|> Result.mapError (\_ -> "Markdown parsing error")
|> findThis
Finally, we have arrived at the solution without any Debug.todo calls.