package main

import (
	"fmt"

	"golang.org/x/exp/constraints"
)

// section: ambiguous
// Convert converts a numeric value to a string
func Convert[T constraints.Ordered](value T) string {
	return fmt.Sprintf("%v", value)
}

// Zero returns the zero value for any type
func Zero[T any]() T {
	var zero T
	return zero
}

func main() {
	// Sometimes the context doesn't provide enough information
	// for the compiler to infer the type

	// This works - type is inferred from the argument:
	result1 := Convert(42)
	fmt.Printf("Convert(42): %s\n", result1)

	// But when creating a function variable, we need explicit types:
	converter := Convert[int] // Must specify T = int
	result2 := converter(123)
	fmt.Printf("converter(123): %s\n", result2)

	// Zero function always needs explicit instantiation
	// because there's no argument to infer from:
	zeroInt := Zero[int]()
	zeroString := Zero[string]()

	fmt.Printf("Zero int: %d\n", zeroInt)
	fmt.Printf("Zero string: '%s'\n", zeroString)

	// This would NOT compile:
	// unknown := Zero()  // compiler error: cannot infer T
}

// section: ambiguous
