code: func coerceValue(ttype Input, value interface{}) interface{} {
  	if isNullish(value) {
  		return nil
  	}
  	switch ttype := ttype.(type) {
  	case *NonNull:
  		return coerceValue(ttype.OfType, value)
  	case *List:
  		var values = []interface{}{}
  		valType := reflect.ValueOf(value)
  		if valType.Kind() == reflect.Slice {
  			for i := 0; i < valType.Len(); i++ {
  				val := valType.Index(i).Interface()
  				values = append(values, coerceValue(ttype.OfType, val))
  			}
  			return values
  		}
  		return append(values, coerceValue(ttype.OfType, value))
  	case *InputObject:
  		var obj = map[string]interface{}{}
  		valueMap, _ := value.(map[string]interface{})
  		if valueMap == nil {
  			valueMap = map[string]interface{}{}
  		}
  
  		for name, field := range ttype.Fields() {
  			fieldValue := coerceValue(field.Type, valueMap[name])
  			if isNullish(fieldValue) {
  				fieldValue = field.DefaultValue
  			}
  			if !isNullish(fieldValue) {
  				obj[name] = fieldValue
  			}
  		}
  		return obj
  	case *Scalar:
  		if parsed := ttype.ParseValue(value); !isNullish(parsed) {
  			return parsed
  		}
  	case *Enum:
  		if parsed := ttype.ParseValue(value); !isNullish(parsed) {
  			return parsed
  		}
  	}
  
  	return nil
  }
docs: // Given a type and any value, return a runtime value coerced to match the type.