Created
June 12, 2019 12:48
-
-
Save oleksii-demedetskyi/f28171d4f2aac622c5d9b3d07000b117 to your computer and use it in GitHub Desktop.
Redux reducer composed using new @functionBuilder api
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
protocol Action {} | |
struct Reducer<State> { | |
let reduce: (State, Action) -> State | |
} | |
struct Increment: Action {} | |
struct Decrement: Action {} | |
func on<State, A>(_ actionType: A.Type, reduce: @escaping (State, A) -> State) -> Reducer<State> { | |
Reducer<State> { state, action in | |
guard let action = action as? A else { | |
return state | |
} | |
return reduce(state, action) | |
} | |
} | |
@_functionBuilder | |
struct ReduceBuilder<State> { | |
static func buildBlock(_ reducers: Reducer<State>...) -> Reducer<State> { | |
return Reducer<State> { state, action in | |
var state = state | |
for reducer in reducers { | |
state = reducer.reduce(state, action) | |
} | |
return state | |
} | |
} | |
} | |
func reduce<State>(@ReduceBuilder<State> builder: @escaping () -> Reducer<State>) -> Reducer<State> { | |
return builder() | |
} | |
let counter: Reducer<Int> = reduce { | |
on(Increment.self) { state, action in state + 1 } | |
on(Decrement.self) { state, action in state - 1 } | |
} | |
var state = 0 | |
state = counter.reduce(state, Increment()) | |
state = counter.reduce(state, Increment()) | |
state = counter.reduce(state, Increment()) | |
state = counter.reduce(state, Decrement()) | |
state = counter.reduce(state, Decrement()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment