Skip to content

Instantly share code, notes, and snippets.

@bahmutov
Created August 10, 2017 15:37
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bahmutov/9ab5368209365d41ccff942d960284f1 to your computer and use it in GitHub Desktop.
Save bahmutov/9ab5368209365d41ccff942d960284f1 to your computer and use it in GitHub Desktop.
Kleisli composition example (JSON parsing + deep property)
// following along https://medium.com/@luijar/kliesli-compositions-in-javascript-7e1a7218f0c4
const R = require('ramda')
const Maybe = require('ramda-fantasy').Maybe
// parse JSON string into object
// parse :: String -> Object | Null
function parse(s) {
try {
return JSON.parse(s)
} catch (e) {
return null
}
}
// prop :: (Object, String) -> Object | String | Null
const prop = (obj, name) => obj[name]
// maybeParseJson :: String -> Maybe
const maybeParseJson = json => Maybe.toMaybe(parse(json))
// maybeProp :: String -> Object -> Maybe
const maybeProp = prop => obj => Maybe.toMaybe(obj[prop])
// convert a "simple" function to return Maybe
// https://github.com/ramda/ramda-fantasy/blob/master/docs/Maybe.md#maybeof
const maybeUpper = R.compose(Maybe.of, R.toUpper)
// a typical user object is
/*
{
user:
{
address:
{
state: "fl"
}
}
}
*/
// getStateCode :: String -> Maybe
const getStateCode = R.composeK(
maybeUpper,
maybeProp('state'),
maybeProp('address'),
maybeProp('user'),
maybeParseJson
)
module.exports = getStateCode
// testing getStateCode
const getStateCode = require('./index')
it('extracts from valid string', () => {
const s = '{"user": {"address": {"state": "in"}}}'
const state = getStateCode(s).getOrElse('an error')
console.assert(state === 'IN', state)
})
it('handles invalid JSON string', () => {
// notice missing quotes
const s = '{"user": {"address": {state: in}}}'
const state = getStateCode(s).getOrElse('an error')
console.assert(state === 'an error', state)
})
it('handles missing property', () => {
// notice missing address
const s = '{"user": {}}'
const state = getStateCode(s).getOrElse('an error')
console.assert(state === 'an error', state)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment