Skip to content

Instantly share code, notes, and snippets.

@fvilante
Last active May 9, 2019 07:19
Show Gist options
  • Save fvilante/cf6906d88ec9906828cf807f675d4658 to your computer and use it in GitHub Desktop.
Save fvilante/cf6906d88ec9906828cf807f675d4658 to your computer and use it in GitHub Desktop.
Modeling of parametrized Messages and a Generic Dispatcher
// ============================================================
// 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