如何编写通用函数类型

时间:2016-08-04 15:12:14

标签: generics anonymous-function hacklang

我有一个看起来像这样的界面。

interface Value {
  public function accept<T>(ValueVisitor<T> $visitor): T;
}

由于只有一个方法,我想编写一个将闭包转换为Value实例的类。

final class ClosureValue implements Value {
  public function __construct(
    private (function<T>(ValueVisitor<T>): T) $f
  ) {}

  public function accept<T>(ValueVisitor<T> $visitor): T {
    $f = $this->f;
    return $f($visitor);
  }
}

但是,<T>类型中的function<T>(ValueVisitor<T>): T是语法错误。无论我把<T>放在哪里,它都不会解析。

我怎么能在Hack中写这个?

2 个答案:

答案 0 :(得分:-1)

现在我无法尝试,如果它的工作,但这可能有效:

$(document).on('keypress keydown',function (e) {
    return $(".popup").is(":visible") && e.which !== 9 && e.which !== 32;
});

答案 1 :(得分:-1)

它为我工作很好......

classes.hh

<?hh // strict

class ValueVisitor<T>
{
    protected T $value;
    public function __construct(T $new) { $this->value = $new; }
    public function get(): T { return $this->value; }
}

interface Value { public function accept<T>(ValueVisitor<T> $visitor): T; }

final class ClosureValue<T> implements Value {
    public function __construct(
    private (function(ValueVisitor<T>) : T) $myF
) {

}

public function accept(ValueVisitor<T> $visitor) : T {
    $fn = $this->myF;
    return $fn($visitor);
}

// main.hh

<?hh // strict

class MyClass
{
    public function __construct(
        protected string $myVal
    ) { }

    public function getMyVal(): string { return $this->myVal; }
}

function main<T>() : void
{
    $visitor = new ValueVisitor(12);
    $val = new ClosureValue(function(ValueVisitor<int> $f): int {
        return $f->get();
    });

    echo $val->accept($visitor);


    $visitor2 = new ValueVisitor('Foo');
    $val2 = new ClosureValue(function(ValueVisitor<string> $f): string {
        return $f->get();
    });

    echo $val2->accept($visitor2);

    $visitor3 = new ValueVisitor(new MyClass("asd"));
    $val3 = new ClosureValue(function(ValueVisitor<MyClass> $f): MyClass {
        return $f->get();
    });

    print_r($val3->accept($visitor2));
}

index.hh

<?hh // partial    

require 'classes.hh';
require 'helpers.hh';
require 'main.hh';

main();