scala 泛型函数参考

mic*_*nko 4 functional-programming scala

我有几个具有相同签名的通用函数:

def f1[A, B](v: A, f: (A, B) => B): B = ...

def f2[A, B](v: A, f: (A, B) => B): B = ...
Run Code Online (Sandbox Code Playgroud)

我需要定义一个g可以接受以下任何函数的函数 ( f1 f2):

def g(f: ????) = ...
Run Code Online (Sandbox Code Playgroud)

g内部使用多个参数类型,所以我不能像这样参数化它:

def g[A, B](f: (A, (A, B) => B) => B) = ...
Run Code Online (Sandbox Code Playgroud)

Mat*_*ndt 7

在 Scala 2 中确实没有更好的方法来做到这一点。尽管您的解决方案有点奇怪,因为FunctionHolder\'sapply方法将返回一个函数对象并且本身不接受任何参数 \xe2\x80\x93比需要的要复杂一点。所以你可以这样做:

\n
trait FunctionHolder {\n  def apply[A, B](v: A, f: (A, B) => B): B\n}\n\ndef g(f: FunctionHolder) = \xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n

但这实际上并没有那么好。

\n

在 Scala 3 中,有多态函数类型可以以更简洁的方式执行此操作:

\n
def g(f: [A, B] => (A, (A, B) => B) => B) = \xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n

也就是说,我不相信该类型签名确实是您想要的。请记住,当您定义带有类型参数的函数时,它需要适用于用户可能提供的所有可能的类型参数。无法对此签名\xe2\x80\xa6 执行此操作

\n
def f1[A, B](v: A, f: (A, B) => B): B\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x80\xa6 因为当我有这样的函数时,我可以轻松编写类型的表达式Nothing

\n
f1[Unit, Nothing]((), (a: Unit, b: Nothing) => b)\n
Run Code Online (Sandbox Code Playgroud)\n

Nothing除非你作弊(例如抛出异常或进入无限循环或类似的东西),否则不可能编写类型的表达式。所以类型签名告诉我你在作弊

\n

如果你想了解更多此类推理,请免费搜索\xe2\x80\x9c定理!\xe2\x80\x9d

\n