总结

我们已经认识了几个不同的 functor,但它们的数量其实是无限的。有一些值得注意的可迭代数据类型(iterable data structure)我们没有介绍,像 tree、list、map 和 pair 等,以及所有你能说出来的。eventstream 和 observable 也都是 functor。其他的 functor 可能就是拿来做封装或者仅仅是模拟类型。我们身边到处都有 functor 的身影,本书也将会大量使用它们。

用多个 functor 参数调用一个函数怎么样呢?处理一个由不纯的或者异步的操作组成的有序序列怎么样呢?要应对这个什么都装在盒子里的世界,目前我们工具箱里的工具还不全。下一章,我们将直奔 monad 而去。

第 9 章: Monad

练习

  1. require('../../support');
  2. var Task = require('data.task');
  3. var _ = require('ramda');
  4. // 练习 1
  5. // ==========
  6. // 使用 _.add(x,y) 和 _.map(f,x) 创建一个能让 functor 里的值增加的函数
  7. var ex1 = undefined
  8. //练习 2
  9. // ==========
  10. // 使用 _.head 获取列表的第一个元素
  11. var xs = Identity.of(['do', 'ray', 'me', 'fa', 'so', 'la', 'ti', 'do']);
  12. var ex2 = undefined
  13. // 练习 3
  14. // ==========
  15. // 使用 safeProp 和 _.head 找到 user 的名字的首字母
  16. var safeProp = _.curry(function (x, o) { return Maybe.of(o[x]); });
  17. var user = { id: 2, name: "Albert" };
  18. var ex3 = undefined
  19. // 练习 4
  20. // ==========
  21. // 使用 Maybe 重写 ex4,不要有 if 语句
  22. var ex4 = function (n) {
  23. if (n) { return parseInt(n); }
  24. };
  25. var ex4 = undefined
  26. // 练习 5
  27. // ==========
  28. // 写一个函数,先 getPost 获取一篇文章,然后 toUpperCase 让这片文章标题变为大写
  29. // getPost :: Int -> Future({id: Int, title: String})
  30. var getPost = function (i) {
  31. return new Task(function(rej, res) {
  32. setTimeout(function(){
  33. res({id: i, title: 'Love them futures'})
  34. }, 300)
  35. });
  36. }
  37. var ex5 = undefined
  38. // 练习 6
  39. // ==========
  40. // 写一个函数,使用 checkActive() 和 showWelcome() 分别允许访问或返回错误
  41. var showWelcome = _.compose(_.add( "Welcome "), _.prop('name'))
  42. var checkActive = function(user) {
  43. return user.active ? Right.of(user) : Left.of('Your account is not active')
  44. }
  45. var ex6 = undefined
  46. // 练习 7
  47. // ==========
  48. // 写一个验证函数,检查参数是否 length > 3。如果是就返回 Right(x),否则就返回
  49. // Left("You need > 3")
  50. var ex7 = function(x) {
  51. return undefined // <--- write me. (don't be pointfree)
  52. }
  53. // 练习 8
  54. // ==========
  55. // 使用练习 7 的 ex7 和 Either 构造一个 functor,如果一个 user 合法就保存它,否则
  56. // 返回错误消息。别忘了 either 的两个参数必须返回同一类型的数据。
  57. var save = function(x){
  58. return new IO(function(){
  59. console.log("SAVED USER!");
  60. return x + '-saved';
  61. });
  62. }
  63. var ex8 = undefined