func MatchFunction(me interface{}, other interface{}) bool {
	meType := reflect.TypeOf(me)
	otherType := reflect.TypeOf(other)
	if meType.Kind() == reflect.Ptr && otherType.Kind() != reflect.Ptr {
		return false
	}
	if otherType.Kind() == reflect.Ptr && meType.Kind() != reflect.Ptr {
		return false
	}
	if meType.Kind() == reflect.Ptr {
		meType = meType.Elem()
	}
	if otherType.Kind() == reflect.Ptr {
		otherType = otherType.Elem()
	}
	if meType.Kind() != reflect.Func {
		return false
	}
	if otherType.Kind() != reflect.Func {
		return false
	}
	if otherType.NumIn() != meType.NumIn() {
		return false
	}
	if otherType.NumOut() != meType.NumOut() {
		return false
	}
	for i := 0; i < meType.NumIn(); i++ {
		item := meType.In(i)
		otherItem := otherType.In(i)
		if item.Kind() != reflect.Func && !MatchElement(item, otherItem, true) {
			return false
		}
		if item.Kind() == reflect.Func && !MatchFunction(item, otherItem) {
			return false
		}
	}
	for i := 0; i < meType.NumOut(); i++ {
		item := meType.Out(i)
		otherItem := otherType.Out(i)
		if item.Kind() != reflect.Func && !MatchElement(item, otherItem, true) {
			return false
		}
		if item.Kind() == reflect.Func && !MatchFunction(item, otherItem) {
			return false
		}
	}
	return true
}
MatchFunction attempts to validate if giving types are functions and
exactly match in arguments and returns.
package reflection
import (
	"errors"
	"reflect"
	"strings"
)
var ErrNotFunction = errors.New("Not A Function Type")
func IsFuncType(elem interface{}) bool {
	_, err := FuncType(elem)
	if err != nil {
		return false
	}
	return true
}
func FuncValue(elem interface{}) (reflect.Value, error) {
	tl := reflect.ValueOf(elem)
	if tl.Kind() == reflect.Ptr {
		tl = tl.Elem()
	}
	if tl.Kind() != reflect.Func {
		return tl, ErrNotFunction
	}
	return tl, nil
}
func FuncType(elem interface{}) (reflect.Type, error) {
	tl := reflect.TypeOf(elem)
	if tl.Kind() == reflect.Ptr {
		tl = tl.Elem()
	}
	if tl.Kind() != reflect.Func {
		return nil, ErrNotFunction
	}
	return tl, nil
}
func MatchElement(me interface{}, other interface{}, allowFunctions bool) bool {
	meType := reflect.TypeOf(me)
	otherType := reflect.TypeOf(other)
	if meType.Kind() == reflect.Ptr && otherType.Kind() != reflect.Ptr {
		return false
	}
	if otherType.Kind() == reflect.Ptr && meType.Kind() != reflect.Ptr {
		return false
	}
	if meType.Kind() == reflect.Ptr {
		meType = meType.Elem()
	}
	if otherType.Kind() == reflect.Ptr {
		otherType = otherType.Elem()
	}
	if meType.Kind() == reflect.Func {
		if allowFunctions {
			return MatchFunction(me, other)
		}
		return false
	}
	if otherType.AssignableTo(meType) {
		return true
	}
	return true
}