2

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?

Sander Toonen
  • 3,463
  • 35
  • 54
  • Have you tried it without a result type? Like in the docs http://docs.hhvm.com/manual/en/language.generators.syntax.php – PKeidel Apr 13 '15 at 10:46
  • Yes, that works but kind-of defeats the purpose. In order to be able to defined the script as _strict_ hack, a return type must be defined. – Sander Toonen Apr 13 '15 at 11:16

1 Answers1

4

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 yielding ints, and the void since you don't care what values are sent into the generator.

Josh Watzman
  • 7,060
  • 1
  • 18
  • 26