Last active
May 9, 2019 07:19
-
-
Save fvilante/cf6906d88ec9906828cf807f675d4658 to your computer and use it in GitHub Desktop.
Modeling of parametrized Messages and a Generic Dispatcher
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
// ============================================================ | |
// Sample code: | |
// Modeling of parametrized Messages and a Generic Dispatcher | |
// | |
// Author: @fvilante | |
// ============================================================ | |
// Messages (or events, or actions...) | |
interface Increment { | |
kind: 'Increment', | |
toSub: number, | |
foo: undefined | |
} | |
const Increment = (toSub: number): Increment => | |
({ kind: 'Increment', toSub, foo: undefined }) | |
interface Decrement { | |
kind: 'Decrement', | |
toAdd: number | |
}; | |
const Decrement = (toAdd: number): Decrement => | |
({ kind: 'Decrement', toAdd }) | |
type Message = | |
| Increment | |
| Decrement | |
// Model | |
interface Model { | |
count: number | |
} | |
const initialModel: Model = { | |
count: 0 | |
} | |
// Update | |
type Update = (_: Model) => (_: Message) => Model | |
const update: Update = model => msg => { | |
switch (msg.kind) { | |
case 'Decrement': | |
return { | |
...model, | |
count: model.count - msg.toAdd | |
} | |
case 'Increment': | |
return { | |
...model, | |
count: model.count + msg.toSub | |
} | |
default: | |
const exhaustiveCheck: never = msg | |
} | |
} | |
// reducer | |
type Reduce = (_:Update) => (_:Model) => (_:Message[]) => Model | |
const reduce: Reduce = update => model => msgs => { | |
let m = model | |
for (let i of msgs) { | |
m = update(m)(i) | |
} | |
const r = m | |
return r | |
} | |
// use | |
const main = () => { | |
const msgs = [ | |
Increment(10), | |
Increment(5), | |
Decrement(40), | |
] | |
console.log('Before', initialModel) // Before { count: 0 } | |
const m = reduce(update)(initialModel)(msgs) | |
console.log('After', m) // After { count: -25 } | |
} | |
// execution | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment