Advertisement
Guest User

Untitled

a guest
Jun 28th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.25 KB | None | 0 0
  1. const R = new LaRamda()
  2.  
  3. /**
  4. * A subset of custom implementations of functions from
  5. * the Ramda library. (all in Lamda form)
  6. * - thanks to @xgrommx for uniq, intersection, where, evolve,
  7. * applySpec, defaultTo, both, either, cond, zipWith
  8. */
  9. function LaRamda () {
  10. const I = x => x
  11. const K = x => y => x
  12. const S = f => g => x => f(x)(g(x))
  13. this.identity = I
  14. this.always = K
  15. this.tap = S(K)
  16.  
  17. const _ifElse = (pred, ifTrue, ifFalse) => x => pred(x) ? ifTrue(x) : ifFalse(x)
  18. this.curryN = (n, fn, ...args) => args.length < n ?
  19. this.curryN.bind(this, n, fn, ...args) : fn(...args)
  20. this.curry = (fn, ...args) => _ifElse(
  21. K(fn.length > args.length),
  22. K(this.curry.bind(this, fn, ...args)),
  23. K(fn(...args))
  24. )
  25. this.curry = (fn) => (...args) => fn.length > args.length ? fn.bind(fn, ...args) : fn(...args)
  26. this.concat = this.curry((a, b) => a.concat(b))
  27. this.apply = this.curry((fn, args) => fn(...args))
  28. this.prop = this.curry((k, obj) => obj[k])
  29. this.of = (...args) => [...args]
  30. this.head = ([a, ...xs]) => a
  31. this.last = (xs) => this.concat([], xs).slice(-1).pop()
  32. this.tail = (x, ...xs) => this.concat([], xs)
  33. this.init = (xs) => this.concat([], xs).slice(0, -1)
  34. this.map = this.curry((fn, xs) => xs.map(fn))
  35. this.reduce = this.curry((fn, def) => xs => this.concat([], xs).reduce(fn, def))
  36. this.reduceR = this.curry((fn, def) => xs => this.concat([], xs).reduceRight(fn, def))
  37. this.uniq = this.uniq = arr => [...new Set(arr)]
  38. this.intersection = a => b => a.filter(Set.prototype.has, new Set(b))
  39. this.join = this.curry((sep, xs) => this.concat([], xs).join(sep))
  40. this.prepend = this.curry((x, xs) => [x, ...xs])
  41. this.compose = (...fns) => (...input) => this.reduceR(
  42. (x, fn) => fn(x), this.last(fns)(...input))(this.init(fns)
  43. )
  44. this.equals = this.curry((a, b) => a === b)
  45. this.nthArg = n => (...args) => args[n]
  46. this.filter = this.curry((fn, xs) => xs.filter(fn))
  47. this.repeat = this.curry((x, n) => Array(n).fill(x))
  48. this.zip = xs => this.compose(
  49. this.filter(I),
  50. this.map((y, i) => xs.length >= i ? [xs[i], y] : null)
  51. )
  52. this.pair = this.curry((v, i) => [v, i])
  53. this.subtract = this.curry((a, b) => a - b)
  54. this.both = (a, b) => (...args) => [a, b].every(f => f(...args))
  55. this.either = (a, b) => (...args) => [a, b].some(f => f(...args))
  56. this.defaultTo = n => this.ifElse(Boolean, I, K(n))
  57. this.ifElse = this.curry(_ifElse)
  58. this.when = this.curry((pred, ifTrue, x) => pred(x) ? ifTrue(x) : x)
  59. this.lt = this.curry((n1, n2) => n1 < n2)
  60. this.gt = n => this.complement(this.lt(n))
  61. this.lte = this.curry((n1, n2) => n1 <= n2)
  62. this.gte = n => this.complement(this.lte(n))
  63. this.length = this.prop('length')
  64. this.not = x => !x
  65. this.complement = pred => x => this.not(pred(x))
  66. this.isNil = x => x === null || typeof x === 'undefined'
  67. this.either = this.curry((pred1, pred2) => x => !!(pred1(x) || pred2(x)))
  68.  
  69.  
  70. this.has = this.curry((prop, obj) => obj.hasOwnProperty(prop))
  71. this.is = this.curry((cons, t) => this.not(this.isNil(t)) && t.constructor === cons)
  72. this.propSatisfies = this.curry((pred, key, obj) =>
  73. this.compose(pred, this.prop(key))(obj))
  74. this.converge = (convergeOnFn, argFns) => (...args) => this.apply(convergeOnFn)(
  75. this.map((fn, i) => this.apply(fn)(args))(argFns))
  76. this.useWith = (useOnFn, argFns) => (...args) => this.apply(useOnFn)(
  77. this.map((arg, i) => (argFns[i] || I)(arg))(args)
  78. )
  79. this.takeWhile = pred => this.compose(this.prop('v'), this.reduce(
  80. (acc, x) => !acc.f && pred(x) ?
  81. { f: false, v: [...acc.v, x] } :
  82. { v: acc.v, f: true }, { v: [], f: false }
  83. ))
  84. this.groupWith = pred => this.compose(this.prop('v'), this.reduce(
  85. (acc, x) =>
  86. typeof acc.p !== 'undefined' && pred(acc.p, x) ?
  87. { p: acc.p, v: [...acc.v.slice(0, -1), [].concat(...acc.v.slice(-1), [x]) ] } :
  88. { p: x, v: [...acc.v, [x]] }, { v: [] }
  89. ))
  90. this.where = this.curry((predicateObj, obj) => {
  91. return Reflect.ownKeys(obj).every(key => {
  92. return predicateObj[key](obj[key])
  93. });
  94. })
  95. this.unless = this.curry((condition, f) => this.cond([
  96. [(...args) => condition(...args), I],
  97. [K(true), (...args) => f(...args)],
  98. ]))
  99. this.applySpec = transformObj => (...args) => {
  100. return Reflect.ownKeys(transformObj).reduce((acc, key) => {
  101. return Object.assign({}, acc, {
  102. [key]: typeof transformObj[key] === 'function' ?
  103. transformObj[key](...args) :
  104. this.applySpec(transformObj[key])(...args),
  105. })
  106. }, {});
  107. }
  108. const _evolve = transformObj => obj => {
  109. return Reflect.ownKeys(obj).reduce((acc, key) => {
  110. return Object.assign({}, acc, {
  111. [key]: transformObj[key] ?
  112. (typeof transformObj[key] === 'function'
  113. ? transformObj[key](obj[key])
  114. : _evolve(transformObj[key])(obj[key])) : obj[key],
  115. })
  116. }, {});
  117. }
  118. this.zipWith = f => a => b => {
  119. const size = Math.min(a.length, b.length);
  120. const [x, y] = [a, b].map(xs => xs.slice(0, size));
  121.  
  122. return x.reduce((acc, next, i) => {
  123. return [...acc, f(next)(y[i])];
  124. }, []);
  125. }
  126. this.cond = conditions => {
  127. return (...args) => {
  128. for (const condition of conditions) {
  129. if (condition[0](...args)) {
  130. return condition[1](...args)
  131. }
  132. }
  133. }
  134. }
  135. this.evolve = this.curry(_evolve)
  136. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement