Skip to content

Instantly share code, notes, and snippets.

@cdmcmahon
Last active November 6, 2019 23:51
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save cdmcmahon/b365652e2e819adc1039fd38f94eabee to your computer and use it in GitHub Desktop.
In the Point-Free series on application architecture and state management, they define a series of ways to compose reducers. Sometimes, however, it seems that the signature of reducers can complicate the signature of these different compositions. I found creating a typealias for reducers separated the concern of understanding the concept of redu…
// In the Point-Free series on application architecture and state management,
// they define a series of ways to compose reducers. Sometimes, however, it seems
// that the signature of reducers can complicate the signature of these different
// compositions. I found creating a typealias for reducers separated the concern of
// understanding the concept of reducers and understanding their higher order
// constructions, especially when starting to write my own.
// Adding a typealias for Reducer can make certain parts a bit more readable
typealias Reducer<Value, Action> = (inout Value, Action) -> Void
func combine<Value, Action>(
_ reducers: Reducer<Value, Action>...
) -> Reducer<Value, Action> {
return { value, action in
for reducer in reducers {
reducer(&value, action)
}
}
}
final class Store<Value, Action>: ObservableObject {
let reducer: Reducer<Value, Action>
@Published private(set) var value: Value
init(initialValue: Value, reducer: @escaping Reducer<Value, Action>) {
self.reducer = reducer
self.value = initialValue
}
func send(_ action: Action) {
self.reducer(&self.value, action)
}
}
func pullback<LocalValue, GlobalValue, LocalAction, GlobalAction>(
_ reducer: @escaping Reducer<LocalValue, LocalAction>,
value: WritableKeyPath<GlobalValue, LocalValue>,
action: WritableKeyPath<GlobalAction, LocalAction?>
) -> Reducer<GlobalValue, GlobalAction> {
return { globalValue, globalAction in
guard let localAction = globalAction[keyPath: action] else { return }
reducer(&globalValue[keyPath: value], localAction)
}
}
func logging<Value, Action>(
_ reducer: @escaping Reducer<Value, Action>
) -> Reducer<Value, Action> {
return { value, action in
reducer(&value, action)
print("Action: \(action)")
print("Value:")
dump(value)
print("---")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment