Know what your software does. Explain why it did it.
NeoHaskell helps teams model a change as a request, a decision, a recorded event, and a view. Those concepts stay visible from design through implementation, so the current state has a history and the next change has a place to start.
A Current Value Is A Summary
A balance of €70 tells you where an account ended, but not how it got there. In an application backed by a persistent event store, accepted events can provide the history from which current state is reconstructed.
Current value only
The new value replaces the old one. The reason is elsewhere.
Accepted history
The current value is reconstructed from the recorded facts.
History answers only the questions the application was designed to preserve. Reasons, evidence, attribution, privacy, and retention are still explicit design choices.
One Model, Carried Through The Toolchain
Event sourcing and domain modeling can be implemented in many languages. NeoHaskell is designed to make their core concepts part of the application model rather than conventions every team must recreate.
- 1Command / request
- Represents an intended change
- 2Entity
- Reconstructs current state from prior events
- 3Decision
- Accepts or refuses the request
- 4Event
- Records an accepted domain fact
- 5Query
- Builds a view for a particular question
Types can make some invalid combinations unrepresentable. The compiler catches type mismatches and can require exhaustive handling where code uses closed alternatives. Tests exercise the policies and boundary cases they cover. None of these checks can decide whether a business rule is fair, complete, or right for the real world.
Add Behavior In Visible Slices
A behavior slice follows one useful change from request through decision and accepted event to the view needed next. Stable boundaries keep change local instead of forcing contributors to reinterpret the whole system.
Implicit dependencies
Hidden shared assumptions widen the change surface. Red blocks represent rework in earlier behavior.
Visible slices and contracts
Each slice gives the team a boundary to implement and test. Shared contracts remain explicit coordination points.
Correct Mistakes Without Erasing Them
If a withdrawal is recorded twice, changing the balance repairs the number but not the history. A domain can instead define a request to reverse the duplicate, a decision that checks whether it is allowed, and a compensating event that records the correction.
Human- and agent-initiated changes can be routed through the same request and authorization path. Automation can assist implementation or submit a request; the team still owns the rule, the authority to apply it, and the evidence that must be retained.
Use It Where History Earns Its Cost
This approach is strongest in domains with meaningful lifecycles: orders, accounts, approvals, grants, projects, memberships, and other systems where disputes, audit, or accountability matter.
Simple content sites, disposable prototypes, static lookup data, and workflows with no meaningful history may be better served by conventional tools. Event sourcing introduces modeling and operational costs; those costs should solve a real problem.