Skip to content

Instantly share code, notes, and snippets.

View dewey92's full-sized avatar
🌴

Jihad D. Waspada dewey92

🌴
View GitHub Profile
@dewey92
dewey92 / readerMonadOop.ts
Last active April 25, 2018 20:03
My Reader Monad Oop Impl
interface IReader<D, A> {
map<B>(f: (value: A) => B): IReader<D, B>,
flatMap<B>(f: (value: A) => IReader<D, B>): IReader<D, B>,
run(deps: D): A
}
const Reader = <D, A>(fn: (deps: D) => A): IReader<D, A> => {
const run = (deps: D) => fn(deps);
return {
map: f => Reader((deps: D) => f(run(deps))),
@dewey92
dewey92 / readerMonad.ts
Last active April 23, 2018 13:37
My Reader Monad Impl
interface Reader<D, A> {
(deps: D): A
}
const fmap = <D, A, B>(f: (v: A) => B, readerA: Reader<D, A>): Reader<D, B> =>
deps => f(readerA(deps))
const bind = <D, A, B>(f: (v: A) => Reader<D, B>, readerA: Reader<D, A>): Reader<D, B> =>
deps => f(readerA(deps))(deps)
// reducerHelper.js
export const createAsyncReducer = (initialState, asyncAction) =>
(state = initialState, action) => {
switch (action.type) {
case asyncAction.request.type:
return {
...state,
asyncState: AsyncState.loading
}
case asyncAction.success.type:
@dewey92
dewey92 / createAsyncAction.js
Last active April 22, 2018 10:29
Async Action Creators
const createAction = actionName => Object.assign(
payload => ({
type: actionName,
payload
}),
{ type: actionName } // <- Inject `type` attribute to the action func
)
const createAsyncAction = actionName => ({
request: createAction(actionName + '_REQUEST'),
@dewey92
dewey92 / commonReducer-2.js
Last active April 21, 2018 10:59
User with Post reducer
export default (state = initialState, action) => {
switch (action.type) {
case 'GET_USER_REQUEST':
return {
...state,
user: {
...state.user,
asyncState: AsyncState.loading
}
}
const AsyncState = {
idle: 'idle',
loading: 'loading',
loaded: 'loaded',
error: 'error'
}
const initialState = {
user: {
data: {},
@dewey92
dewey92 / EntryCodeChalange.md
Created February 23, 2018 14:31
Entry Challange

Write some application with messy code and file structures. This messy app

is:

  1. Inconsistent in naming convention
  2. Baking business logic into one big function
  3. Using quite a number of Imperative Programming styles
  4. ...

handle:

  1. Side effects (hitting API, sending email after registering, etc)
// composeK :: Monad m => ((y β†’ m z), (x β†’ m y), …, (a β†’ m b)) β†’ (a β†’ m z)
const composeK = (...fns) => init => {
if (!fns.length) throw new Error('Need at least 1 argument')
const lastArg = fns.pop();
return fns.reduceRight((acc, x) => acc.bind(x), lastArg(init))
}
const getHalfOfChildsAge = compose(
safeDivisionBy(2),
getAge,
getChild
)
// getChild :: Person β†’ Maybe Person
// getAge :: Person β†’ Maybe Number
// safeDivisionBy :: Number β†’ Number β†’ Maybe Number
// getChild :: Person β†’ Maybe Person
const getChild = p => Maybe.of(p.child)
// getAge :: Person β†’ Maybe Number
const getAge = p => Maybe.of(p.age)
// safeDivisionBy :: Number β†’ Number β†’ Maybe Number
const safeDivisionBy = bawah => atas =>
(bawah === 0) ? Nothing() : Maybe.of(atas / bawah)