Guest User

Untitled

a guest
Dec 16th, 2017
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.81 KB | None | 0 0
  1. const Protocol = ([name]) => (def) =>
  2. def.reduce((pro, curr) => {
  3. if (Array.isArray(curr)) {
  4. const [field, fn] = curr
  5. pro[field] = Symbol(`${name}.${field}`)
  6. pro[Protocol.methods].push({
  7. symbol: pro[field],
  8. fn,
  9. })
  10. pro[Protocol.symbols].push({
  11. name: curr,
  12. symbol: pro[curr],
  13. })
  14. }
  15. else {
  16. pro[curr] = Symbol(`${name}.${curr}`)
  17. pro[Protocol.symbols].push({
  18. name: curr,
  19. symbol: pro[curr],
  20. })
  21. }
  22.  
  23. return pro
  24. }, { [Protocol.methods]: [], [Protocol.symbols]: [], [Protocol.origin]: name })
  25.  
  26. Protocol.methods = Symbol('Protocol.methods')
  27. Protocol.symbols = Symbol('Protocol.symbols')
  28. Protocol.origin = Symbol('Protocol.origin')
  29.  
  30. Protocol.implement = function(target, ...protocols) {
  31. protocols.forEach(protocol => {
  32. protocol[Protocol.methods].forEach(({ symbol, fn }) => {
  33. target.prototype[symbol] = fn
  34. })
  35.  
  36. protocol[Protocol.symbols].forEach(({ name, symbol }) => {
  37. if (!(target[symbol] || target.prototype[symbol])) {
  38. const tn = target.constructor && target.constructor.name || target
  39. throw new TypeError(
  40. `${tn} not correctly implements ${protocol[Protocol.origin]}.\n`
  41. + `${name} not found as ${symbol.toString()}`
  42. )
  43. }
  44. })
  45. })
  46. }
  47.  
  48. const Functor = Protocol`Functor`([
  49. 'map',
  50. ])
  51.  
  52. const map = fn => target => {
  53. if (target[Functor.map]) {
  54. return target[Functor.map](fn)
  55. }
  56. else if (target.map) {
  57. return target.map(fn)
  58. }
  59. throw new TypeError('Not have @@map')
  60. }
  61.  
  62.  
  63. Promise.prototype[Functor.map] = function(fn) {
  64. return this.then(value => fn.call(this, value))
  65. }
  66. Protocol.implement(Promise, Functor)
  67.  
  68. map(console.log)(Promise.resolve(12))
  69.  
  70.  
  71.  
  72. Array.prototype[Functor.map] = function(fn) {
  73. return this.map(fn)
  74. }
  75. Protocol.implement(Array, Functor)
Add Comment
Please, Sign In to add comment