github.com/searKing/golang/go@v1.2.74/util/function/function.go (about)

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package function
     6  
     7  import (
     8  	"github.com/searKing/golang/go/error/exception"
     9  	"github.com/searKing/golang/go/util/class"
    10  	"github.com/searKing/golang/go/util/object"
    11  )
    12  
    13  /**
    14   * Represents a function that accepts one argument and produces a result.
    15   *
    16   * <p>This is a <a href="package-summary.html">functional interface</a>
    17   * whose functional method is {@link #apply(Object)}.
    18   *
    19   * @param <T> the type of the input to the function
    20   * @param <R> the type of the result of the function
    21   *
    22   * @since 1.8
    23   */
    24  type Function interface {
    25  	/**
    26  	 * Applies this function to the given argument.
    27  	 *
    28  	 * @param t the function argument
    29  	 * @return the function result
    30  	 */
    31  	Apply(t interface{}) interface{}
    32  
    33  	/**
    34  	 * Returns a composed function that first applies the {@code before}
    35  	 * function to its input, and then applies this function to the result.
    36  	 * If evaluation of either function throws an exception, it is relayed to
    37  	 * the caller of the composed function.
    38  	 *
    39  	 * @param <V> the type of input to the {@code before} function, and to the
    40  	 *           composed function
    41  	 * @param before the function to apply before this function is applied
    42  	 * @return a composed function that first applies the {@code before}
    43  	 * function and then applies this function
    44  	 * @throws NullPointerException if before is null
    45  	 *
    46  	 * @see #andThen(Function)
    47  	 */
    48  	Compose(before Function) Function
    49  
    50  	/**
    51  	 * Returns a composed function that first applies this function to
    52  	 * its input, and then applies the {@code after} function to the result.
    53  	 * If evaluation of either function throws an exception, it is relayed to
    54  	 * the caller of the composed function.
    55  	 *
    56  	 * @param <V> the type of output of the {@code after} function, and of the
    57  	 *           composed function
    58  	 * @param after the function to apply after this function is applied
    59  	 * @return a composed function that first applies this function and then
    60  	 * applies the {@code after} function
    61  	 * @throws NullPointerException if after is null
    62  	 *
    63  	 * @see #compose(Function)
    64  	 */
    65  	AndThen(before Function) Function
    66  }
    67  
    68  /**
    69   * Returns a function that always returns its input argument.
    70   *
    71   * @param <T> the type of the input and output objects to the function
    72   * @return a function that always returns its input argument
    73   */
    74  func Identity() Function {
    75  	return FunctionFunc(func(t interface{}) interface{} {
    76  		return t
    77  	})
    78  }
    79  
    80  type FunctionFunc func(t interface{}) interface{}
    81  
    82  // Apply calls f(t).
    83  func (f FunctionFunc) Apply(t interface{}) interface{} {
    84  	return f(t)
    85  }
    86  
    87  func (f FunctionFunc) Compose(before Function) Function {
    88  	object.RequireNonNil(before)
    89  	return FunctionFunc(func(t interface{}) interface{} {
    90  		return f.Apply(before.Apply(t))
    91  	})
    92  }
    93  
    94  func (f FunctionFunc) AndThen(after Function) Function {
    95  	object.RequireNonNil(after)
    96  	return FunctionFunc(func(t interface{}) interface{} {
    97  		return after.Apply(f.Apply(t))
    98  	})
    99  }
   100  
   101  type AbstractFunction struct {
   102  	class.Class
   103  }
   104  
   105  func (f *AbstractFunction) Apply(t interface{}) interface{} {
   106  	panic(exception.NewIllegalStateException1("called wrong Apply method"))
   107  }
   108  
   109  func (f *AbstractFunction) Compose(before Function) Function {
   110  	object.RequireNonNil(before)
   111  	return FunctionFunc(func(t interface{}) interface{} {
   112  		return f.GetDerivedElse(f).(Function).Apply(before.Apply(t))
   113  	})
   114  }
   115  
   116  func (f *AbstractFunction) AndThen(after Function) Function {
   117  	object.RequireNonNil(after)
   118  	return FunctionFunc(func(t interface{}) interface{} {
   119  		return after.Apply(f.GetDerivedElse(f).(Function).Apply(t))
   120  	})
   121  }