I think part of the issue is that they didn’t explain what is gained by adding generics on methods. You’re right that a few examples here are useful.
Without generics:
‘’’
type Stream[T any] struct{ ... }
func (s Stream[T]) MapInt(f func(T) int) Stream[int] { ... }
func (s Stream[T]) MapString(f func(T) string) Stream[string] { ... }
‘’’
Then later you need to map floats:
‘’’
func (s Stream[T]) MapFloat64(f func(T) float64) Stream[float64] { ... }
‘’’
Then later someone outside the package wants to map a custom type. Too bad! They’ll need to make some custom wrapper that doesn’t follow the pattern.
With the genetics approach the semantics are defined once and usable in all scenarios. You don’t need to keep adding methods; instead the caller can provide the mapping function. Common mapping functions could be pre defined for convenience.