func (c *Composite) Underlying() Type {
	return c
}
Underlying returns itself as the underlying type of c.
package types
import (
	"bytes"
	"fmt"
	"go.nickng.io/asyncpi"
)
type Type interface {
	Underlying() Type
	String() string
}
type anyType struct{}
func newAnyType() *anyType {
	return &anyType{}
}
func (t *anyType) Underlying() Type {
	return t
}
func (t *anyType) String() string {
	return "interface{}"
}
type Base struct {
	name string
}
func NewBase(name string) *Base {
	return &Base{name}
}
func (b *Base) Underlying() Type {
	return b
}
func (b *Base) String() string {
	return b.name
}
type Chan struct {
	elem Type
}
func NewChan(elem Type) *Chan {
	return &Chan{elem}
}
func (c *Chan) Elem() Type {
	return c.elem
}
func (c *Chan) Underlying() Type {
	return c
}
func (c *Chan) String() string {
	return fmt.Sprintf("chan %s", c.Elem().String())
}
type Composite struct {
	elems []Type
}
func NewComposite(t ...Type) *Composite {
	comp := &Composite{}
	comp.elems = append(comp.elems, t...)
	return comp
}
func (c *Composite) Elems() []Type {
	return c.elems
}