Scala 泛型函数参考
scala generic function reference
我有几个具有相同签名的通用函数:
def f1[A, B](v: A, f: (A, B) => B): B = ...
def f2[A, B](v: A, f: (A, B) => B): B = ...
我需要定义一个函数 g
可以接受任何这些函数 (f1
f2
):
def g(f: ????) = ...
g
内部使用了多种参数类型,所以我不能像那样参数化它:
def g[A, B](f: (A, (A, B) => B) => B) = ...
经过一番摸索,得出以下结论:
g(new FunctionHolder {
def apply[A, B](): (A, (A, B) => B) => B = f1
})
def g(f: FunctionHolder) = f()(..., (a, b) => ...)
abstract class FunctionHolder {
def apply[A, B](): (A, (A, B) => B) => B
}
但这看起来不对。
希望有更简洁的方法来做到这一点
在 Scala 2 中确实没有更好的方法。虽然你的解决方案有点奇怪,因为 FunctionHolder
的 apply
方法将 return 一个函数object 并且本身不接受任何参数——这比它需要的要复杂一点。所以你可以这样做:
trait FunctionHolder {
def apply[A, B](v: A, f: (A, B) => B): B
}
def g(f: FunctionHolder) = …
但这并没有那么好。
在 Scala 3 中,polymorphic function types 可以更简洁地执行此操作:
def g(f: [A, B] => (A, (A, B) => B) => B) = …
也就是说,我不相信那个类型签名真的是你想要的。请记住,当您定义带有类型参数的函数时,它需要为用户可能提供的 所有 可能的类型参数工作。无法为此签名完成…
def f1[A, B](v: A, f: (A, B) => B): B
... 因为当我有这样的函数时,我可以很容易地写出 Nothing
:
类型的表达式
f1[Unit, Nothing]((), (a: Unit, b: Nothing) => b)
并且不可能编写 Nothing
类型的表达式,除非你作弊(例如抛出异常或进入无限循环或类似的东西)。所以类型签名告诉我你在作弊
如果你想了解更多关于这种推理的信息,请搜索“免费定理!”
我有几个具有相同签名的通用函数:
def f1[A, B](v: A, f: (A, B) => B): B = ...
def f2[A, B](v: A, f: (A, B) => B): B = ...
我需要定义一个函数 g
可以接受任何这些函数 (f1
f2
):
def g(f: ????) = ...
g
内部使用了多种参数类型,所以我不能像那样参数化它:
def g[A, B](f: (A, (A, B) => B) => B) = ...
经过一番摸索,得出以下结论:
g(new FunctionHolder {
def apply[A, B](): (A, (A, B) => B) => B = f1
})
def g(f: FunctionHolder) = f()(..., (a, b) => ...)
abstract class FunctionHolder {
def apply[A, B](): (A, (A, B) => B) => B
}
但这看起来不对。
希望有更简洁的方法来做到这一点
在 Scala 2 中确实没有更好的方法。虽然你的解决方案有点奇怪,因为 FunctionHolder
的 apply
方法将 return 一个函数object 并且本身不接受任何参数——这比它需要的要复杂一点。所以你可以这样做:
trait FunctionHolder {
def apply[A, B](v: A, f: (A, B) => B): B
}
def g(f: FunctionHolder) = …
但这并没有那么好。
在 Scala 3 中,polymorphic function types 可以更简洁地执行此操作:
def g(f: [A, B] => (A, (A, B) => B) => B) = …
也就是说,我不相信那个类型签名真的是你想要的。请记住,当您定义带有类型参数的函数时,它需要为用户可能提供的 所有 可能的类型参数工作。无法为此签名完成…
def f1[A, B](v: A, f: (A, B) => B): B
... 因为当我有这样的函数时,我可以很容易地写出 Nothing
:
f1[Unit, Nothing]((), (a: Unit, b: Nothing) => b)
并且不可能编写 Nothing
类型的表达式,除非你作弊(例如抛出异常或进入无限循环或类似的东西)。所以类型签名告诉我你在作弊
如果你想了解更多关于这种推理的信息,请搜索“免费定理!”