package main

import "fmt"

// Number adalah constraint bernama: int, float64, dan tipe turunannya.
type Number interface {
	~int | ~float64
}

// Milimeter punya underlying type int sehingga masuk himpunan ~int.
type Milimeter int

// RataRata memakai constraint bernama Number.
func RataRata[T Number](data []T) T {
	var total T
	for _, v := range data {
		total += v
	}
	return total / T(len(data))
}

// KaliDua memakai constraint literal yang ditulis langsung.
func KaliDua[T ~int | ~float64](nilai T) T {
	return nilai * 2
}

func main() {
	tinggi := []float64{1.62, 1.75, 1.8}
	fmt.Println("Rata-rata tinggi :", RataRata(tinggi))

	suhu := []int{31, 33, 34}
	fmt.Println("Rata-rata suhu   :", RataRata(suhu))

	// Milimeter lolos karena ~int menerima tipe dengan underlying int.
	tebal := []Milimeter{2, 5, 8}
	fmt.Println("Rata-rata tebal  :", RataRata(tebal))

	fmt.Println("KaliDua(21)      :", KaliDua(21))
	fmt.Println("KaliDua(2.5)     :", KaliDua(2.5))
	fmt.Println("KaliDua tebal    :", KaliDua(Milimeter(10)))
}
