Is this a satisfactory implementation of event sourcing using functional programming?
module Account
(*Types*)
type EventAggregate<'Aggregate> = { Event:Event; Aggregate:'Aggregate }
and Command =
| Login of EventAggregate<Account>
| Deposit of EventAggregate<Account>
| Withdrawal of EventAggregate<Account>
and Event =
| LoggedIn of Login
| Deposited of decimal
| Withdrew of decimal
and AccountId = AccountId of string
and FirstName = FirstName of string
and LastName = LastName of string
and Login = { UserId:string; Password:string }
and Account = {
AccountId: AccountId
FirstName: FirstName
LastName: LastName }
(*Functions*)
let appendTo (repo:Map<Event,_>) (plan:EventAggregate<'a>) =
repo.Add (plan.Event , plan.Aggregate)
let getAccount login = {
AccountId= AccountId "myAccountId"
FirstName= FirstName "Scott"
LastName= LastName "Nimrod" }
let interpret cmd repo = cmd |> function
| Login v
| Deposit v -> appendTo repo v
| _ -> repo
(*Client*)
let login = { UserId= "MyUserId"; Password= "MyPassword" }
let account = getAccount login
let loginPlan = { Event= LoggedIn login
Aggregate= account }
let depositPlan = { Event= Deposited 100m
Aggregate= account }
let store = (Login loginPlan , Map.empty)
||> interpret
|> interpret (Deposit depositPlan)