gott.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package gott
  2. import "fmt"
  3. // Exception is a type encapsulating anything contained in panic.
  4. // It implements Error() and therefore can be used as error.
  5. type Exception struct {
  6. e interface{}
  7. }
  8. func (e Exception) Error() string {
  9. return fmt.Sprintf("function panicked")
  10. }
  11. // Tuple is a type encapsulating a slice of interface{}.
  12. type Tuple []interface{}
  13. // Result is a simplification of Either monad. It’s either successful—and
  14. // carries an interface{}—or unsuccessful—and carries an error.
  15. type Result struct {
  16. s interface{}
  17. e error
  18. }
  19. // NewResult creates initial Result passed to functions.
  20. func NewResult(s interface{}) *Result {
  21. return &Result{s, nil}
  22. }
  23. // Bind performs fn on the receiver’s success value and assigns the returned
  24. // values to the receiver if the receiver is successful. In either case,
  25. // Bind returns the receiver.
  26. // Bind operates on functions that return value and error.
  27. func (r *Result) Bind(fn func(...interface{}) (interface{}, error)) *Result {
  28. if r.e == nil {
  29. if s, ok := r.s.(Tuple); ok {
  30. r.s, r.e = fn(s...)
  31. } else {
  32. r.s, r.e = fn(r.s)
  33. }
  34. }
  35. return r
  36. }
  37. // Map performs fn on the receiver’s success value and assigns the returned
  38. // value to the it if the receiver is successful. In either case, Map returns
  39. // the receiver.
  40. // Map operates on functions that are always successful and return only one
  41. // value
  42. func (r *Result) Map(fn func(...interface{}) interface{}) *Result {
  43. if r.e == nil {
  44. if s, ok := r.s.(Tuple); ok {
  45. r.s = fn(s...)
  46. } else {
  47. r.s = fn(r.s)
  48. }
  49. }
  50. return r
  51. }
  52. // Tee performs fn on the receiver’s success value and assigns the returned
  53. // error to the receiver if the receiver is successful. In either case, Tee
  54. // returns the receiver.
  55. // Tee operates on functions that perform side effects and might return an
  56. // error
  57. func (r *Result) Tee(fn func(...interface{}) error) *Result {
  58. if r.e == nil {
  59. r.s = nil
  60. if s, ok := r.s.(Tuple); ok {
  61. r.e = fn(s...)
  62. } else {
  63. r.e = fn(r.s)
  64. }
  65. }
  66. return r
  67. }
  68. // SafeTee performs fn on the receiver’s success value if the receiver is
  69. // successful. In either case, SafeTee returns the receiver.
  70. // SafeTee operates on functions that perform side effects and are always
  71. // successful.
  72. func (r *Result) SafeTee(fn func(...interface{})) *Result {
  73. if r.e == nil {
  74. if s, ok := r.s.(Tuple); ok {
  75. fn(s...)
  76. } else {
  77. fn(r.s)
  78. }
  79. }
  80. return r
  81. }
  82. // Catch performs fn on the receiver’s success value and assigns the returned
  83. // vale to it if the receiver is successful. If fn panics, Catch recovers and
  84. // stores the value passed to panic in receiver’s error as Exception. In either
  85. // case, Catch returns the receiver.
  86. func (r *Result) Catch(fn func(...interface{}) interface{}) (result *Result) {
  87. if r.e == nil {
  88. defer func() {
  89. if err := recover(); err != nil {
  90. r.e = Exception{err}
  91. result = r
  92. }
  93. }()
  94. if s, ok := r.s.(Tuple); ok {
  95. r.s = fn(s...)
  96. } else {
  97. r.s = fn(r.s)
  98. }
  99. }
  100. return r
  101. }
  102. // Handle performs onSuccess on the receiver’s success value if the receiver is
  103. // successful, or onError on the receiver’s error otherwise. In either case,
  104. // Handle returns the receiver.
  105. func (r *Result) Handle(onSuccess func(...interface{}), onError func(error)) *Result {
  106. if r.e == nil {
  107. if s, ok := r.s.(Tuple); ok {
  108. onSuccess(s...)
  109. } else {
  110. onSuccess(r.s)
  111. }
  112. } else {
  113. onError(r.e)
  114. }
  115. return r
  116. }
  117. // Finish returns the values stored in the receiver.
  118. func (r *Result) Finish() (interface{}, error) {
  119. if r.e != nil {
  120. return nil, r.e
  121. } else {
  122. return r.s, nil
  123. }
  124. }