func (patternSelf KindPatternDef) Apply(value interface{}) interface{} {
	return patternSelf.effect(value)
}
Apply Evaluate the result by its given effect function
package fpgo
import (
	"fmt"
	"reflect"
	"regexp"
	"sync"
)
type fnObj func(interface{}) interface{}
func Compose(fnList ...func(...interface{}) []interface{}) func(...interface{}) []interface{} {
	return func(s ...interface{}) []interface{} {
		f := fnList[0]
		nextFnList := fnList[1:]
		if len(fnList) == 1 {
			return f(s...)
		}
		return f(Compose(nextFnList...)(s...)...)
	}
}
func PtrOf(v interface{}) *interface{} {
	return &v
}
func SliceOf(args ...interface{}) []interface{} {
	return args
}
type CurryDef struct {
	fn     func(c *CurryDef, args ...interface{}) interface{}
	result interface{}
	isDone AtomBool
	callM sync.Mutex
	args  []interface{}
}
func (currySelf *CurryDef) New(fn func(c *CurryDef, args ...interface{}) interface{}) *CurryDef {
	c := &CurryDef{fn: fn}
	return c
}
func (currySelf *CurryDef) Call(args ...interface{}) *CurryDef {
	currySelf.callM.Lock()
	if !currySelf.isDone.Get() {
		currySelf.args = append(currySelf.args, args...)
		currySelf.result = currySelf.fn(currySelf, currySelf.args...)
	}
	currySelf.callM.Unlock()
	return currySelf
}
func (currySelf *CurryDef) MarkDone() {
	currySelf.isDone.Set(true)
}
func (currySelf *CurryDef) IsDone() bool {
	return currySelf.isDone.Get()
}
func (currySelf *CurryDef) Result() interface{} {
	return currySelf.result
}
var Curry CurryDef
type Pattern interface {
	Matches(value interface{}) bool
	Apply(interface{}) interface{}
}
type PatternMatching struct {
	patterns []Pattern
}
type KindPatternDef struct {
	kind   reflect.Kind
	effect fnObj
}
type CompTypePatternDef struct {
	compType CompType
	effect   fnObj
}
type EqualPatternDef struct {
	value  interface{}
	effect fnObj
}
type RegexPatternDef struct {
	pattern string
	effect  fnObj
}
type OtherwisePatternDef struct {
	effect fnObj
}
func (patternMatchingSelf PatternMatching) MatchFor(inValue interface{}) interface{} {
	for _, pattern := range patternMatchingSelf.patterns {
		value := inValue
		maybe := Maybe.Just(inValue)
		if maybe.IsKind(reflect.Ptr) {
			ptr := maybe.ToPtr()
			if reflect.TypeOf(*ptr).Kind() == (reflect.TypeOf(CompData{}).Kind()) {
				value = *ptr
			}
		}
		if pattern.Matches(value) {
			return pattern.Apply(value)
		}
	}
	panic(fmt.Sprintf("Cannot match %v", inValue))
}
func (patternSelf KindPatternDef) Matches(value interface{}) bool {
	if Maybe.Just(value).IsNil() {
		return false
	}
	return patternSelf.kind == reflect.TypeOf(value).Kind()
}
func (patternSelf CompTypePatternDef) Matches(value interface{}) bool {
	if Maybe.Just(value).IsPresent() && reflect.TypeOf(value).Kind() == reflect.TypeOf(CompData{}).Kind() {
		return MatchCompType(patternSelf.compType, (value).(CompData))
	}
	return patternSelf.compType.Matches(value)
}
func (patternSelf EqualPatternDef) Matches(value interface{}) bool {
	return patternSelf.value == value
}
func (patternSelf RegexPatternDef) Matches(value interface{}) bool {
	if Maybe.Just(value).IsNil() || reflect.TypeOf(value).Kind() != reflect.String {
		return false
	}
	matches, err := regexp.MatchString(patternSelf.pattern, (value).(string))
	if err == nil && matches {
		return true
	}
	return false
}
func (patternSelf OtherwisePatternDef) Matches(value interface{}) bool {
	return true
}