I'm playing around with Hack for a bit and tried to create a generator function using the yield
keyword. The documentation states that the return type of such a function should be the Continuation
interface. However, when running hh_client
on the source code example of the generator function I get the following output:
./test.php:4:3,7: Invalid yield (Typing[4110])
./test.php:3:17,28: This is an object of type Continuation
./test.php:4:3,7: It is incompatible with an object of type Generator (result of function with 'yield' in the body)
This is test.php:
<?hh
function gen(): Generator<int> {
yield 1;
yield 2;
yield 3;
}
function foo(): void {
foreach (gen() as $x) {
echo $x, "\n";
}
}
foo();
Changing the result type to Generator
gives even more warnings. What is the correct way of typing a generator function?
Any mention of Continuation
in the docs is outdated and wrong. There's an open issue about it.
The correct type is Generator<Tk, Tv, Ts>
-- there are actually three type parameters there. Here's an example of what they mean:
$r = yield $k => $v;
The type of that generator is Generator<Tk, Tv, Ts>
, where Tk
is the type of $k
, Tv
is the type of $v
, and Ts
is the type of $r
.
For your code, this should work:
function gen(): Generator<int, int, void> {
yield 1;
yield 2;
yield 3;
}
The first int
because there is implicitly an integer key; the second int
because you are yield
ing int
s, and the void
since you don't care what values are sent into the generator.