-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Description
Suppose we have a generic function F whose result type is a function. In an expression that calls F and immediately calls the result function, it would be nice to use the arguments to the result function to help determine the type parameters for F.
For example, consider:
func check[X any](t *testing.T) func(X, error) X {
return func(x X, e error) X {
if e != nil {
t.Helper()
t.Fatal(e)
}
return x
}
}
f := check(t)(os.Open("path"))
In Go 1.21.4, this does not compile; the error is "cannot infer X". But there is only one reasonable choice for X: *os.File. In principle, the compiler could figure this out; I don't know how difficult it would be in practice.
In this specific example, the problem can be worked around by changing the order of parameter lists:
func vet[X any](x X, e error) func(t *testing.T) X {
// obvious content omitted
)
f := vet(os.Open("path"))(t)
However, I find this order much less desirable, for various reasons not relevant here. And there are undoubtedly cases where such a workaround is not possible. In particular, if both parameter lists use type parameters:
func foo[X, Y any](X) func(Y) { ... }
then there seems to be no way to write a call foo(x)(y)
without explicitly specifying at least one type parameter.
Like #50285 (comment), this seems to be a request to infer types from the context of a function call, although in a different manner.
There would be some open questions about how far this might go. Could we have
f(1)(2)(3)(4)(5)(6)("seven")
where "seven"
is used to infer a type parameter of f? What if the result type is not a function, but the expression calls a method on the result? Should this work?
type Box[T any] struct{}
func (b Box[T]) hold(T) {}
func crate[T any]() Box[T] {
return Box[T]{}
}
func oops() {
crate().hold("some string")
}
Metadata
Metadata
Assignees
Labels
Type
Projects
Status