使用多态函数作为参数 [英] Using polymorphic function as a parameter
问题描述
我有一个函数exec
,该函数接受3个参数,并将作为第一个参数传递的函数f
应用于其他两个参数-p1
和p2
.
I have a function exec
which accepts 3 parameters and applies a function f
passed as first argument to the other two - p1
and p2
.
def exec[T](f: (T, T) => Boolean, p1: T, p2: T) = f(p1, p2)
如果我事先声明一个将作为参数传递的函数,一切都会很好.
Everything works fine if I declare in advance a function which will be passed as an argument.
以某种方式,编译器可以推断eq
的参数类型,或者换句话说,它可以弄清楚whatever
在这种情况下是Int
Somehow compiler can infer types for arguments of eq
or in other words it can figure out that whatever
in this case is Int
// declaring a function with type parameter (polymorphic method)
def eq[whatever](p1: whatever, p2: whatever) = p1 == p2
// using a declared function
println(exec(eq, 10, 10))
如果我明确指定Int
,如下所示,它也可以正常工作
It also works fine if I explicitly specify Int
as shown below
// specifying type explicitly in function literal
println(exec((p1: Int, p2: Int) => p1 == p2, 10, 10))
// specifying type parameter
println(exec[Int]((p1, p2) => p1 == p2, 10, 10))
问题1
是否有可能无法正常工作?
Is it possible to get below working?
println(exec((p1, p2) => p1 == p2, 10, 10))
例如,通过使用隐式,不同地定义exec
或使用其他某种方式,编译器可以推断出p1和p2的类型,从而不会因missing parameter type
而失败.
For example, by using implicits, defining exec
differently or using some other way making it possible for compiler to infer types of p1 and p2 so that it does not fail with missing parameter type
.
因此,不使用任何显式的类型提示或声明的方法.
So no explicit type hints or declared methods are used.
问题2
编译器如何推断eq
的类型以及为什么它可用于p1 == p2
或p1 != p2
之类的表达式,但对于p1 >= p2
却失败(错误为value >= is not a member of type parameter whatever
)?
How does compiler infer types for eq
and why it works for expressions like p1 == p2
or p1 != p2
but fails for p1 >= p2
(error is value >= is not a member of type parameter whatever
)?
推荐答案
问题1是否有可能使工作低于正常水平?
Question 1 Is it possible to get below working?
如果您可以这样重写exec
:
def exec[T](p1: T, p2: T)(f: (T, T) => Boolean) = f(p1, p2)
然后,编译器将已经知道函数的输入类型.
因此,您将可以这样称呼它:
Then, the compiler will already know the input type of the function.
So, you will be able to call it like this:
println(exec(10, 10) { case (p1, p2) => p1 == p2 })
这是一个常见的习惯用法,首先将普通参数放在一个参数组上,然后再将函数放在单个参数组上.
This is a common idiom, to put plain parameters first and then a function on a single parameter group.
编译器如何推断eq的类型,以及为什么它可用于p1 == p2或p1!= p2之类的表达式,但对于p1> = p2则失败
How does compiler infer types for eq and why it works for expressions like p1 == p2 or p1 != p2 but fails for p1 >= p2
因为, Scala 具有普遍平等(这是人们最批评该语言的东西之一,但对于 Java 互操作).
Because, Scala has universal equality (which is one of the things people most criticize of the language, but it was necessary for Java interop).
因此,您始终可以比较任何类的两个对象是否相等.
这是因为相等性是在 Any 超类中定义的,如下所示.
So, you can always compare two objects of any class for equality.
That is because equality is defined in the Any superclass as follows.
class Any {
def equals(other: Any): Boolean
}
但是,订购不是通用的.
如果需要,您可能想编写一个适用于任何类型的泛型函数,只要有这种类型的订单即可,您可能会对 类型类 .
但这是另一个问题的话题.
But, ordering is not universal.
If you want, you may want to write a generic function which works for any type as long as there is an order for such type, you may be interested in the Ordering
- typeclass.
But that is topic for another question.
这篇关于使用多态函数作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!