Guest User

Untitled

a guest
May 21st, 2018
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.85 KB | None | 0 0
  1. // =============== NOTE ===============
  2. // The implementations below use the term "Iterable" for any value
  3. // which can be iterated and includes all of the following:
  4. // - Array a :: Arrays containing any type
  5. // - Generator a :: Generators returning any type
  6. // - Iterator a :: Iterators returning any type
  7.  
  8.  
  9.  
  10. /********** ARITY FUNCTIONS **********/
  11.  
  12. const monadic = (f) => (a) => a === void 0 ?
  13. monadic(f) :
  14. f(a);
  15. const dyadic = (f) => (a, b) => a === void 0 ?
  16. dyadic(f) :
  17. b === void 0 ?
  18. monadic((_b) => f(a, _b)) :
  19. f(a, b);
  20. const triadic = (f) => (a, b, c) => a === void 0 ?
  21. triadic(f) :
  22. b === void 0 ?
  23. dyadic((_b, _c) => f(a, _b, _c)) :
  24. c === void 0 ?
  25. monadic((_c) => f(a, b, _c)) :
  26. f(a, b, c);
  27.  
  28.  
  29.  
  30. /********** STREAM FUNCTIONS **********/
  31.  
  32. // Takes an iterable collection and turns it into a stream
  33. // toStream :: Iterable -> Iterable
  34. const toStream = monadic((xs) => (function * (a) { yield * a; })(xs));
  35.  
  36. // Takes start, stop and step arguments and returns an iterable
  37. // which returns values until stop is reached. All arguments are optional
  38. // and should be numeric values. If no arguments are given, the resulting
  39. // iterable goes on forever
  40. // range :: Number?, Number?, Number? -> Iterable
  41. const range = (start = 0, end = Infinity, step = 1) => (function * (a, b, c) {
  42. let d = a; while (d < b) { yield d; d += c; }
  43. })(start, end, step);
  44.  
  45. // Takes a variadic number of iterable collections and chains them
  46. // into a single iterable
  47. // chain :: Iterable1 ... IterableN -> Iterable
  48. const chain = (...xs) => (function * () {
  49. for (let x of xs) { for (let y of x) { yield y; } }
  50. })();
  51.  
  52. // Takes a reducer function, a seed value and an iterable collection
  53. // and folds/reduces the collection into the seed value.
  54. // Note: This function returns a final value which might not be iterable!
  55. // fold :: (a, b -> a) -> a -> Iterable -> a
  56. const fold = triadic((fn, seed, xs) => (function * (a, b, c) {
  57. let d = b; for (let e of c) { d = a(d, e); } yield d;
  58. }(fn, seed, xs)));
  59.  
  60. // Takes a mapping function and an iterable collection and maps the
  61. // function over each item in the collection
  62. // map :: (a -> b) -> Iterable -> Iterable
  63. const map = dyadic((fn, xs) => (function * (a, b) {
  64. for (let c of b) { yield a(c); }
  65. }(fn, xs)));
  66.  
  67. // Takes a predicate function and a iterable collection and filters
  68. // all values which satisfy the predicate
  69. // filter :: (a -> Boolean) -> Iterable -> Iterable
  70. const filter = dyadic((fn, xs) => (function * (a, b) {
  71. for (let c of b) { if (a(c)) { yield c; } }
  72. }(fn, xs)));
  73.  
  74. // Takes a number N and an iterable collection and takes N items
  75. // from the collection
  76. // take :: Number -> Iterable -> Iterable
  77. const take = dyadic((n, xs) => (function * (a, b) {
  78. let c = 0; for (let d of b) { if (c < a) { c += 1; yield d; } else { break; } }
  79. })(Math.abs(n), xs));
  80.  
  81. // Takes a predicate function and an iterable collection and
  82. // returns items as long as the predicate is satisfied
  83. // takeWhile :: (a -> Boolean) -> Iterable -> Iterable
  84. const takeWhile = dyadic((fn, xs) => (function * (a, b) {
  85. for (let d of b) { if (fn(d)) { yield d; } else { break; } }
  86. })(fn, xs));
  87.  
  88. // Takes a number N and an iterable collection and drops the first
  89. // N items from the collection
  90. // drop :: Number -> Iterable -> Iterable
  91. const drop = dyadic((n, xs) => (function * (a, b) {
  92. let c = a; for (let d of b) { if (c > 0) { c -= 1; continue; } else { yield d; } }
  93. })(Math.abs(n), xs));
  94.  
  95. // Takes a predicate function and an iterable collection and
  96. // drops items as long as the predicate is satisfied
  97. // dropWhile :: (a -> Boolean) -> Iterable -> Iterable
  98. const dropWhile = dyadic((fn, xs) => (function * (a, b) {
  99. for (let c of b) { if (!a(c)) { continue; } else { yield c; } }
  100. })(fn, xs));
  101.  
  102. // Takes an iterable collection and skips all items which are either
  103. // undefined or null
  104. // keep :: Iterable -> Iterable
  105. const keep = monadic((xs) => (function * (a) {
  106. for (let b of a) { if (b != null) { yield b; } }
  107. })(xs));
  108.  
  109. // Takes a number N and an iterable collection and partitions the
  110. // collection into arrays of N items each
  111. // partition :: Number -> Iterable -> Iterable
  112. const partition = dyadic((n, xs) => (function * (a, b) {
  113. let c = []; for (let d of b) { if (c.length >= n) { yield c; c = [d]; } else { c.push(d); } }
  114. yield c;
  115. })(n, xs));
  116.  
  117. // Takes a function and an iterable collection and partitions the
  118. // collection into arrays each time the function returns a new result
  119. // partitionWith :: (a -> a) -> Iterable -> Iterable
  120. const partitionWith = dyadic((fn, xs) => (function * (a, b) {
  121. let c = [], e, f;
  122. for (let d of b) { e = a(d); if (f === void 0 || e === f) { c.push(d); } else { yield c; c = [d]; } f = e; }
  123. yield c;
  124. })(fn, xs));
  125.  
  126. // Takes an iterable collection and returns only unique items of it
  127. // unique :: Iterable -> Iterable
  128. const unique = monadic((xs) => (function * (a) {
  129. let b = Object.create(null); for (let c of a) { if (b[c] === void 0) { b[c] = c; yield c; } }
  130. })(xs));
Add Comment
Please, Sign In to add comment