refactor(method): model SimaPro method parser state as one Stage ADT#96
Merged
Conversation
The 12-phase fold-based parser kept its phase in a `Phase` enum alongside a flat 13-field `ParseState` whose per-section accumulators (factors, damage impacts, norm/weight maps) were always present, so a phase could disagree with the data it carried. Fold both into a single `Stage` sum type whose constructors hold exactly the accumulator each phase needs, making those impossible combinations unrepresentable. Completed lists and the constant methodology name move to a slim `ParseState`, dropping `step`'s threaded arg. Extract the duplicated leaf logic into pure helpers: `parseCFRow` (the inlined 35-line CF builder), one `parseNameValue` for the three identical name;value rows, `parseNameUnit` for both Name;Unit headers, `buildMethod`, and a `detectMarker`/`stageFor` pair mirroring `SimaPro.Parser.detectSection`. `finalize` now reuses the same `finishCat`/`finishDamage`/`finishNW` finishers via one `finishCurrent` dispatcher instead of re-implementing the builders. `parseNameUnit` is total, removing the partial `head'`/`error`. The finishers guard on non-empty content and `finishCurrent` flushes any trailing block at EOF, so empty blocks are never emitted and a truncated file no longer drops its last block or its methodology — all unreachable on well-formed SimaPro exports, where output is unchanged.
Replace the wildcard arm with explicit no-op cases for the eight stages that carry no in-progress block. The wildcard suppressed the very incomplete-pattern warning the Stage ADT exists to surface: a future accumulator-carrying stage could silently skip its end-of-input flush.
Bind the MethodCF with a bang before wrapping it in Just, restoring the per-row strictness the pre-refactor inline builder had. Without it the spine-strict factor list still held each row as a thunk retaining slices of the source line, accumulating over large method files.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Continues the PR #87 line of cleanup, this time on
Method.ParserSimaPro— the12-phase fold that parses SimaPro LCIA method CSV exports.
The phase lived in a
Phaseenum next to a flat 13-fieldParseStatewhoseper-section accumulators were always present, so the type permitted a phase to
disagree with the data it held. This change folds phase + accumulator into a
single
Stagesum type whose constructors carry exactly what each phase needs,making those impossible states unrepresentable. It also factors out the
duplicated leaf logic and removes a partial function.
What changed
StageADT replacesPhase+ the flat accumulator fields.CatAccum/DamageAccum/NWAccumhold the in-progress block; completed lists and theconstant methodology name move to a slim
ParseState(sostepdrops itsthreaded methodology argument).
stepcase:parseCFRow(the inlined~35-line CF builder), one
parseNameValuefor the three identicalname;valuerows,parseNameUnitfor bothName;Unitheaders,buildMethod,and
detectMarker/stageFormirroring the siblingSimaPro.Parser.detectSection.finalizecollapsed from re-implemented builders to a 6-line read-out thatreuses the same
finishCat/finishDamage/finishNWfinishers asstep, viaone
finishCurrentdispatcher.parseNameUnitis total, deletinghead'and itserrorcall.Behaviour
Output is unchanged on well-formed SimaPro files (verified by tracing the
fixture through every transition). Three harmonisations are unreachable on valid
exports: empty blocks are no longer emitted, and a truncated file lacking a
terminal
Endnow keeps its trailing block and its methodology instead ofdropping them.
Net:
216 insertions, 233 deletionsin one file.Test plan
cabal build lib:volca— clean, no incomplete-pattern warnings on the newStage/stepcabal run lca-tests -- --match "/Method"— 115 examples, 0 failures (14 SimaPro method cases + standalone NW parser among them)