package main

import "fmt"

// Versi 1: satu fungsi per tipe, isi kode terduplikasi.
func MaxInt(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func MaxFloat64(a, b float64) float64 {
	if a > b {
		return a
	}
	return b
}

// Versi 2: satu fungsi untuk semua tipe, tapi tanpa type safety.
func MaxAny(a, b any) any {
	na, okA := a.(float64)
	nb, okB := b.(float64)
	if !okA || !okB {
		return nil
	}
	if na > nb {
		return a
	}
	return b
}

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

// Versi 3: satu fungsi generik, type safety tetap terjaga.
func Max[T Number](a, b T) T {
	if a > b {
		return a
	}
	return b
}

func main() {
	fmt.Println("MaxInt(3, 7)      :", MaxInt(3, 7))
	fmt.Println("MaxFloat64(2.5, 1.5):", MaxFloat64(2.5, 1.5))

	// Versi any: bekerja untuk float64...
	fmt.Println("MaxAny(2.5, 1.5)  :", MaxAny(2.5, 1.5))
	// ...tetapi gagal diam-diam untuk int, baru terlihat saat runtime.
	fmt.Println("MaxAny(3, 7)      :", MaxAny(3, 7))

	// Versi generik: int dan float64 ditangani satu fungsi.
	fmt.Println("Max(3, 7)         :", Max(3, 7))
	fmt.Println("Max(2.5, 1.5)     :", Max(2.5, 1.5))
}
