Now the abstract sequence type of "LINQ in Go" https://github.com/nukata/linq-in-go can be written as type Enumerator(type T) func(yield func(element T))
and the "Select" method can be written as func (loop Enumerator(T)) Select(f func(T) T) Enumerator(T) {
return func(yield func(T)) {
loop(func(element T) {
value := f(element)
yield(value)
})
}
}
You can call this method with type-safety as follows. Yay! func main() {
squares := Range(1, 3).Select(func(x int) int { return x * x })
squares(func(num int) {
fmt.Println(num)
})
}
// Output:
// 1
// 4
// 9
See https://go2goplay.golang.org/p/b0ugT68QAy2 for the complete code.And, for generality, you should write the method actually as follows. func (loop Enumerator(T)) Select(type R)(f func(T) R) Enumerator(R) {
return func(yield func(R)) {
loop(func(element T) {
value := f(element)
yield(value)
})
}
}
However, you will get the error message then: type checking failed for main
prog.go2:17:33: methods cannot have type parameters
According to https://go.googlesource.com/proposal/+/refs/heads/master/des... this seems an intended restriction:> Although methods of a generic type may use the type's parameters, methods may not themselves have additional type parameters. Where it would be useful to add type arguments to a method, people will have to write a suitably parameterized top-level function. > This is not a fundamental restriction but it complicates the language specification and the implementation. For now, we have to write it as https://go2goplay.golang.org/p/mGOx3SWiFXq and I feel it rather inelegant. Good grief |