You wouldn't have to add explicit type annotations within the body; that would clearly not be consistent with current type-checker behavior.
A one-way constraint is like the status quo for type-checking a variable binding:
let x = 15
return x + UInt(27)
This doesn't type-check because type information only flows "one way" through the variable binding: we decide that x: Int
without considering that x
is required to be convertible to UInt
on the next line.
Another way of understanding the use of one-way constraints in function builders is that they're as if the closure was transformed to assign all the statement results into locals. So given this closure:
Sequential {
Conv2D<Float>(...)
AvgPool2D<Float>(...)
Flatten<Float>()
Dense<Float>(...)
Dense<Float>(...)
}
Instead of thinking of the transform like this:
Sequential {
LayerBuilder.buildBlock(
Conv2D<Float>(...),
AvgPool2D<Float>(...),
Flatten<Float>(),
Dense<Float>(...),
Dense<Float>(...))
}
Think of it more like this:
Sequential {
let a = Conv2D<Float>(...)
let b = AvgPool2D<Float>(...)
let c = Flatten<Float>()
let d = Dense<Float>(...)
let e = Dense<Float>(...)
return LayerBuilder.buildBlock(a, b, c, d, e)
}