在Hacklang中结合多种通用类型



我正在尝试从hack中的下划线实现降低功能。在下划线中,减少功能具有以下行为:

如果没有将备忘录传递给最初的降低调用,则不会在列表的第一个元素上调用ITEMERE。相反,第一个元素是作为在列表中下一个元素的iTerateE调用中作为备忘录传递的。

我尝试实现该功能的尝试:

function reduce<T, Tresult>(
  Iterable<T> $iterable,
  (function(?Tresult, T):Tresult) $fn,
  ?Tresult $memo=null):?Tresult {
    if (is_null($memo)) {
      $memo = $iterable->firstValue();
      $iterable = $iterable->skip(1);
    }
    foreach ($iterable as $value) {
      $memo = $fn($memo, $value);
    }
    return $memo;
}

这会导致错误:

Invalid return type (Typing[4110])  
  This is a value of generic type Tresult  
  It is incompatible with a value of generic type T  
    via this generic Tv

我如何告诉类型检查器T == Tresult is_null($memo)

我注意到该行

$memo = $iterable->firstValue();

T类型的值分配给$memo。这似乎是错误的; $memo在声明中为?Tresult类型,并在此处分配了类型Tresult的值:

$memo = $fn($memo, $value);

您能解释为什么$memo在一开始就分配了T类型的值?您怎么知道TTresult是相同的?我没有看到任何证据表明这两种类型被限制为同一件事。类型的检查器在此处给您一个错误,因为此程序不是TypeAfe;如果T是动物,而Tresult是果实,并且有人通过无效的水果经过,则无法从序列中取出果实。

另外,我发现reduce返回可无效的结果很奇怪。当然,它应该返回给定结果类型的结果,否?

如果您希望此功能根据参数的无效具有两种不同的行为,那么为什么不简单地具有两个函数呢?

function reduce1<T, Tresult>(
  Iterable<T> $iterable,
  (function(Tresult, T):Tresult) $fn,
  Tresult $memo): Tresult {
    foreach ($iterable as $value) {
      $memo = $fn($memo, $value);
    }
    return $memo;
}
function reduce2<T>(
  Iterable<T> $iterable,
  (function(T, T):T) $fn): T {
    return reduce1($iterable->skip(1), $fn, $iterable->firstValue());
}

那里,现在我们有两种不同形式的减少形式,它们都是类型。

相关内容

  • 没有找到相关文章

最新更新