func (set *Set) Union(s Seq) *Set {
	if set == nil {
		return ToSet(s)
	}
	cset := set.clone()
	var el interface{}
	var ok bool
	for {
		if el, s, ok = s.FirstRest(); !ok {
			return cset
		} else if cset, ok = cset.SetVal(el); ok {
			cset.size++
		}
	}
}
Union returns a Set with all of the elements of the original Set along with
everything in the given Seq. If an element is present in both the Set and the
Seq, the element in the Seq overwrites. Completes in O(M*log(N)), with M
being the number of elements in the Seq and N the number of elements in the
Set
package seq
import (
	"bytes"
	"fmt"
	"hash/crc32"
	"reflect"
)
type Setable interface {
	Hash(uint32) uint32
	Equal(interface{}) bool
}
func hash(v interface{}, i uint32) uint32 {
	switch vt := v.(type) {
	case Setable:
		return vt.Hash(i) % ARITY
	case uint32:
		return (i + vt) % ARITY
	case uint:
		return hash(uint32(vt), i)
	case uint8:
		return hash(uint32(vt), i)
	case uint64:
		return hash(uint32(vt), i)
	case int:
		return hash(uint32(vt), i)
	case int8:
		return hash(uint32(vt), i)
	case int16:
		return hash(uint32(vt), i)
	case int32:
		return hash(uint32(vt), i)
	case int64:
		return hash(uint32(vt), i)
	case float32:
		return hash(uint32(vt), i)
	case float64:
		return hash(uint32(vt), i)
	case string:
		return hash([]byte(vt), i)
	case []rune:
		return hash([]byte(string(vt)), i)
	case []byte:
		return crc32.ChecksumIEEE(vt) % ARITY
	default:
		err := fmt.Sprintf("%s not hashable", reflect.TypeOf(v))
		panic(err)
	}
}
func equalDirected(v1, v2 interface{}) bool {
	if v1t, ok := v1.(Setable); ok {
		return v1t.Equal(v2)
	} else if v1t, ok := v1.(Comparable); ok {
		if v2t, ok := v2.(Seq); ok {
			return v1t.Equal(v2t)
		}
	}
	return false
}
func equal(v1, v2 interface{}) bool {
	if equalDirected(v1, v2) {
		return true
	} else if equalDirected(v2, v1) {
		return true
	} else if v1t, ok := v1.([]byte); ok {
		if v2t, ok := v2.([]byte); ok {
			return bytes.Equal(v1t, v2t)
		}
		return false
	}
	return v1 == v2
}
const ARITY = 32
type Set struct {
	val interface{}
	full bool
	kids []*Set
	size uint64
}
func NewSet(vals ...interface{}) *Set {
	if len(vals) == 0 {
		return nil
	}
	set := new(Set)
	for i := range vals {
		set.setValDirty(vals[i], 0)
	}
	set.size = uint64(len(vals))
	return set
}
func (set *Set) Hash(i uint32) uint32 {
	sum := uint32(0)
	s := Seq(set)
	var el interface{}
	var ok bool
	for {
		if el, s, ok = s.FirstRest(); !ok {
			return sum
		}
		sum += hash(el, i)
	}
}
func (set *Set) Equal(v interface{}) bool {
	set2, ok := v.(*Set)
	if !ok {
		return false
	}
	if set.Size() != set2.Size() {
		return false
	}
	sset := Seq(set)
	var el interface{}
	for {
		el, sset, ok = sset.FirstRest()
		if !ok {
			return true
		} else if _, ok = set2.GetVal(el); !ok {
			return false
		}
	}
}
func (set *Set) shallowTrySetOrInit(val interface{}) (bool, bool) {
	if !set.full {
		set.val = val
		set.full = true
		return true, false
	} else if equal(set.val, val) {
		set.val = val
		set.full = true
		return true, true
	} else if set.kids == nil {
		set.kids = make([]*Set, ARITY)
	}
	return false, false
}
func (set *Set) setValDirty(val interface{}, i uint32) {
	if ok, _ := set.shallowTrySetOrInit(val); ok {
		return
	}
	h := hash(val, i)
	if kid := set.kids[h]; kid != nil {
		kid.setValDirty(val, i+1)
	} else {
		set.kids[h] = NewSet(val)
	}
}
func (set *Set) clone() *Set {
	var newkids []*Set
	if set.kids != nil {
		newkids = make([]*Set, ARITY)
		copy(newkids, set.kids)
	}
	cs := &Set{
		val:  set.val,
		full: set.full,
		kids: newkids,
		size: set.size,
	}
	return cs
}
func (set *Set) internalSetVal(val interface{}, i uint32) (*Set, bool) {
	if set == nil {
		return NewSet(val), true
	}
	cset := set.clone()
	if ok, prev := cset.shallowTrySetOrInit(val); ok {
		return cset, !prev
	}
	h := hash(val, i)
	newkid, ok := cset.kids[h].internalSetVal(val, i+1)
	cset.kids[h] = newkid
	return cset, ok
}
func (set *Set) SetVal(val interface{}) (*Set, bool) {
	nset, ok := set.internalSetVal(val, 0)
	if ok {
		if set == nil {
			nset.size = 1
		} else {
			nset.size = set.size + 1
		}
	}
	return nset, ok
}
func (set *Set) internalDelVal(val interface{}, i uint32) (*Set, bool) {
	if set == nil {
		return nil, false
	} else if set.full && equal(val, set.val) {
		cset := set.clone()
		cset.val = nil
		cset.full = false
		return cset, true
	} else if set.kids == nil {
		return set, false
	}
	h := hash(val, i)
	if newkid, ok := set.kids[h].internalDelVal(val, i+1); ok {
		cset := set.clone()
		cset.kids[h] = newkid
		return cset, true
	}
	return set, false
}
func (set *Set) DelVal(val interface{}) (*Set, bool) {
	nset, ok := set.internalDelVal(val, 0)
	if ok && nset != nil {
		nset.size--
	}
	return nset, ok
}
func (set *Set) internalGetVal(val interface{}, i uint32) (interface{}, bool) {
	if set == nil {
		return nil, false
	} else if set.full && equal(val, set.val) {
		return set.val, true
	} else if set.kids == nil {
		return nil, false
	}
	h := hash(val, i)
	return set.kids[h].internalGetVal(val, i+1)
}
func (set *Set) GetVal(val interface{}) (interface{}, bool) {
	return set.internalGetVal(val, 0)
}
func (set *Set) internalFirstRest() (interface{}, *Set, bool) {
	if set == nil {
		return nil, nil, false
	}
	if set.kids != nil {
		var el interface{}
		var rest *Set
		var ok bool
		for i := range set.kids {
			if el, rest, ok = set.kids[i].internalFirstRest(); ok {
				cset := set.clone()
				cset.kids[i] = rest
				return el, cset, true
			}
		}
	}
	if !set.full {
		return nil, nil, false
	}
	return set.val, nil, true
}
func (set *Set) FirstRest() (interface{}, Seq, bool) {
	el, restSet, ok := set.internalFirstRest()
	if ok && restSet != nil {
		restSet.size--
	}
	return el, Seq(restSet), ok
}
func (set *Set) String() string {
	return ToString(set, "#{", "}#")
}
func (set *Set) Size() uint64 {
	if set == nil {
		return 0
	}
	return set.size
}