是否有任何语言在作为参数传递的函数上实现保留的泛型?

Do any languages implement retained generics on functions passed as parameters?

运行 今天在 F# 中跨越这个:

let test<'a> (f: 'a -> unit) =
    let x = f 123
    let y = f "wow"
    ()

这会产生编译器错误,因为通用参数在每次调用 test<'a> 时必须相同,如下所述: 传递映射函数时类型推断不起作用

虽然这是有道理的,但我很好奇是否还有其他语言实现了类似的功能——也许是某种 "parameter-level generics"?

作为跟进,实施这样的事情有哪些挑战?

当然可以。在 Haskell 中,这样的东西被称为 "higher rank types":它们是允许您 "move quantification inside parentheses":

的类型
test :: (forall a. a -> ()) -> ()
test f = let x = f 123
             y = f "wow"
         in ()

在"challenge"中也描述了link给出的:

Rank-N type reconstruction is undecidable in general, and some explicit type annotations are required in their presence.

不过,据我所知,只有 rank-2 类型是可判定的(参见 here)。这就是为什么在 GHC 中有两个不同的标志来启用它们。

人们也可以声称 C++ 支持这一点,因为它在参数多态性方面很奇怪但非常强大。

template<typename T>
void test(T f)
{
  std::cout << f(123)   << std::endl;
  std::cout << f("wow") << std::endl;
}

int main()
{
  test([](auto const & v) 
    { 
      // Note: This is a compile-time test
      if (std::is_same_v<int, std::decay_t<decltype(v)>>)
      {
        return 0;
      }
      else
      {
        return 1;
      }
    });
}