func TypesDisjointUnion(s1 Types, s2 Types) Types {
	result := s1.Copy()
	result.AddTypes(s2)
	return result
}
TypesDisjointUnion merges this and other, with a safety check that no type is overwritten.
If an attempt is made to overwrite a type, this function panics
package astmodel
import (
	"fmt"
	"github.com/pkg/errors"
)
type Types map[TypeName]TypeDefinition
func (types Types) Add(def TypeDefinition) {
	key := def.Name()
	if _, ok := types[key]; ok {
		panic(fmt.Sprintf("type already defined: %v", key))
	}
	types[key] = def
}
func (types Types) FullyResolve(t Type) (Type, error) {
	tName, ok := t.(TypeName)
	for ok {
		tDef, found := types[tName]
		if !found {
			return nil, errors.Errorf("couldn't find definition for %v", tName)
		}
		t = tDef.Type()
		tName, ok = t.(TypeName)
	}
	return t, nil
}
func (types Types) AddAll(otherDefinitions []TypeDefinition) {
	for _, t := range otherDefinitions {
		types.Add(t)
	}
}
func (types Types) AddTypes(otherTypes Types) {
	for _, t := range otherTypes {
		types.Add(t)
	}
}
func (types Types) AddAllowDuplicates(def TypeDefinition) error {
	if !types.Contains(def.Name()) {
		types.Add(def)
		return nil
	}
	existing := types[def.Name()]
	if !def.Type().Equals(existing.Type()) {
		return errors.Errorf("type definition for %q has two shapes", existing.Name())
	}
	return nil
}
func (types Types) Where(predicate func(definition TypeDefinition) bool) Types {
	result := make(Types)
	for _, t := range types {
		if predicate(t) {
			result[t.Name()] = t
		}
	}
	return result
}
func (types Types) Except(otherTypes Types) Types {
	return types.Where(func(def TypeDefinition) bool {
		return !otherTypes.Contains(def.Name())
	})
}
func (types Types) Contains(name TypeName) bool {
	_, ok := types[name]
	return ok
}