123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- package gott
- import "fmt"
- // Exception is a type encapsulating anything contained in panic.
- // It implements Error() and therefore can be used as error.
- type Exception struct {
- e interface{}
- }
- func (e Exception) Error() string {
- return fmt.Sprintf("function panicked")
- }
- // Tuple is a type encapsulating a slice of interface{}.
- type Tuple []interface{}
- // Result is a simplification of Either monad. It’s either successful—and
- // carries an interface{}—or unsuccessful—and carries an error.
- type Result struct {
- s interface{}
- e error
- }
- // NewResult creates initial Result passed to functions.
- func NewResult(s interface{}) *Result {
- return &Result{s, nil}
- }
- // Bind performs fn on the receiver’s success value and assigns the returned
- // values to the receiver if the receiver is successful. In either case,
- // Bind returns the receiver.
- // Bind operates on functions that return value and error.
- func (r *Result) Bind(fn func(...interface{}) (interface{}, error)) *Result {
- if r.e == nil {
- if s, ok := r.s.(Tuple); ok {
- r.s, r.e = fn(s...)
- } else {
- r.s, r.e = fn(r.s)
- }
- }
- return r
- }
- // Map performs fn on the receiver’s success value and assigns the returned
- // value to the it if the receiver is successful. In either case, Map returns
- // the receiver.
- // Map operates on functions that are always successful and return only one
- // value
- func (r *Result) Map(fn func(...interface{}) interface{}) *Result {
- if r.e == nil {
- if s, ok := r.s.(Tuple); ok {
- r.s = fn(s...)
- } else {
- r.s = fn(r.s)
- }
- }
- return r
- }
- // Tee performs fn on the receiver’s success value and assigns the returned
- // error to the receiver if the receiver is successful. In either case, Tee
- // returns the receiver.
- // Tee operates on functions that perform side effects and might return an
- // error
- func (r *Result) Tee(fn func(...interface{}) error) *Result {
- if r.e == nil {
- r.s = nil
- if s, ok := r.s.(Tuple); ok {
- r.e = fn(s...)
- } else {
- r.e = fn(r.s)
- }
- }
- return r
- }
- // SafeTee performs fn on the receiver’s success value if the receiver is
- // successful. In either case, SafeTee returns the receiver.
- // SafeTee operates on functions that perform side effects and are always
- // successful.
- func (r *Result) SafeTee(fn func(...interface{})) *Result {
- if r.e == nil {
- if s, ok := r.s.(Tuple); ok {
- fn(s...)
- } else {
- fn(r.s)
- }
- }
- return r
- }
- // Catch performs fn on the receiver’s success value and assigns the returned
- // vale to it if the receiver is successful. If fn panics, Catch recovers and
- // stores the value passed to panic in receiver’s error as Exception. In either
- // case, Catch returns the receiver.
- func (r *Result) Catch(fn func(...interface{}) interface{}) (result *Result) {
- if r.e == nil {
- defer func() {
- if err := recover(); err != nil {
- r.e = Exception{err}
- result = r
- }
- }()
- if s, ok := r.s.(Tuple); ok {
- r.s = fn(s...)
- } else {
- r.s = fn(r.s)
- }
- }
- return r
- }
- // Handle performs onSuccess on the receiver’s success value if the receiver is
- // successful, or onError on the receiver’s error otherwise. In either case,
- // Handle returns the receiver.
- func (r *Result) Handle(onSuccess func(...interface{}), onError func(error)) *Result {
- if r.e == nil {
- onSuccess(r.s)
- if s, ok := r.s.(Tuple); ok {
- onSuccess(s...)
- } else {
- onSuccess(r.s)
- }
- } else {
- onError(r.e)
- }
- return r
- }
- // Finish returns the values stored in the receiver.
- func (r *Result) Finish() (interface{}, error) {
- if r.e != nil {
- return nil, r.e
- } else {
- return r.s, nil
- }
- }
|