For example we have a feature reducer like this:
// selectCard :: String -> Action Stringexport const selectCard = createAction(SELECT_CARD)// showFeedback :: String -> Action Stringexport const showFeedback = createAction(SHOW_FEEDBACK)// reducer :: Action a -> (State AppState ()) | Nullconst reducer = ({ type, payload }) => { switch (type) { case SELECT_CARD: return answer(payload) case SHOW_FEEDBACK: return feedback(payload) } return null}export default reducer
First of all, we can replace 'swtich' statement with normal Object:
const actionReducer = { SELECT_CARD: answer, SHOW_FEEDBACK: feedback} // reducer :: Action a -> (State AppState ()) | Nullconst reducer = ({ type, payload }) => (actionReducer[type] || Function.prototype)(payload)
In case of ´actionReducer[type]´ return undefined, we default a function by `Function.prototype`, ready to take a payload.
const reducer = ({ type, payload }) => (actionReducer[type] || Function.prototype)(payload)
This type of code is suitable for using 'Maybe'.
// createReducer :: ActionReducer -> Reducerexport const createReducer = actionReducer => ({ type, payload }) => prop(type, actionReducer) .map(applyTo(payload))
Refactor:
// showFeedback :: String -> Action String export const showFeedback = createAction(SHOW_FEEDBACK)const reducer = createReducer({ SELECT_CARD: answer, SHOW_FEEDBACK: feedback})// reducer :: Action a -> (State AppState ()) | Null// const reducer = ({ type, payload }) => // (actionReducer[type] || Function.prototype)(payload)export default reducer
For this workflow, the following code should also be chagned to handle Maybe type:
// Fromimport turn from './turn'//reducer :: (AppState, Action a) -> AppStateconst reducer = (prev, action) => const result = turn(action) return isSameType(State, result) ? result.execWith(prev) : prev}export default reducer // Toimport turn from './turn'//reducer :: (AppState, Action a) -> AppStateconst reducer = (prev, action) => turn(action) .chain(safe(isSameType(State)))// ? result.execWith(prev) // : prevexport default reducer
Here ´turn(action)´ return a Maybe type, we still need to check whether inside Maybe, it is `State` type,
.chain(safe(isSameType(State)))
If it is, then we call `execWith` otherwise we return previous state:
const reducer = (prev, action) => turn(action) .chain(safe(isSameType(State))) .map(execWith(prev)) .option(prev)