总结

组合像一系列管道那样把不同的函数联系在一起,数据就可以也必须在其中流动——毕竟纯函数就是输入对输出,所以打破这个链条就是不尊重输出,就会让我们的应用一无是处。

我们认为组合是高于其他所有原则的设计原则,这是因为组合让我们的代码简单而富有可读性。另外范畴学将在应用架构、模拟副作用和保证正确性方面扮演重要角色。

现在我们已经有足够的知识去进行一些实际的练习了,让我们来编写一个示例应用。

第 6 章: 示例应用

练习

  1. require('../../support');
  2. var _ = require('ramda');
  3. var accounting = require('accounting');
  4. // 示例数据
  5. var CARS = [
  6. {name: "Ferrari FF", horsepower: 660, dollar_value: 700000, in_stock: true},
  7. {name: "Spyker C12 Zagato", horsepower: 650, dollar_value: 648000, in_stock: false},
  8. {name: "Jaguar XKR-S", horsepower: 550, dollar_value: 132000, in_stock: false},
  9. {name: "Audi R8", horsepower: 525, dollar_value: 114200, in_stock: false},
  10. {name: "Aston Martin One-77", horsepower: 750, dollar_value: 1850000, in_stock: true},
  11. {name: "Pagani Huayra", horsepower: 700, dollar_value: 1300000, in_stock: false}
  12. ];
  13. // 练习 1:
  14. // ============
  15. // 使用 _.compose() 重写下面这个函数。提示:_.prop() 是 curry 函数
  16. var isLastInStock = function(cars) {
  17. var last_car = _.last(cars);
  18. return _.prop('in_stock', last_car);
  19. };
  20. // 练习 2:
  21. // ============
  22. // 使用 _.compose()、_.prop() 和 _.head() 获取第一个 car 的 name
  23. var nameOfFirstCar = undefined;
  24. // 练习 3:
  25. // ============
  26. // 使用帮助函数 _average 重构 averageDollarValue 使之成为一个组合
  27. var _average = function(xs) { return reduce(add, 0, xs) / xs.length; }; // <- 无须改动
  28. var averageDollarValue = function(cars) {
  29. var dollar_values = map(function(c) { return c.dollar_value; }, cars);
  30. return _average(dollar_values);
  31. };
  32. // 练习 4:
  33. // ============
  34. // 使用 compose 写一个 sanitizeNames() 函数,返回一个下划线连接的小写字符串:例如:sanitizeNames(["Hello World"]) //=> ["hello_world"]。
  35. var _underscore = replace(/\W+/g, '_'); //<-- 无须改动,并在 sanitizeNames 中使用它
  36. var sanitizeNames = undefined;
  37. // 彩蛋 1:
  38. // ============
  39. // 使用 compose 重构 availablePrices
  40. var availablePrices = function(cars) {
  41. var available_cars = _.filter(_.prop('in_stock'), cars);
  42. return available_cars.map(function(x){
  43. return accounting.formatMoney(x.dollar_value);
  44. }).join(', ');
  45. };
  46. // 彩蛋 2:
  47. // ============
  48. // 重构使之成为 pointfree 函数。提示:可以使用 _.flip()
  49. var fastestCar = function(cars) {
  50. var sorted = _.sortBy(function(car){ return car.horsepower }, cars);
  51. var fastest = _.last(sorted);
  52. return fastest.name + ' is the fastest';
  53. };