[英]Using polymorphic function as a parameter
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
.我有一个 function exec
程序,它接受 3 个参数并应用 function f
作为第一个参数传递给其他两个 - p1
和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.如果我提前声明一个 function 将作为参数传递,一切正常。
Somehow compiler can infer types for arguments of eq
or in other words it can figure out that whatever
in this case is Int
不知何故,编译器可以推断出eq
的 arguments 的类型, whatever
换句话说,它可以找出在这种情况下是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))
It also works fine if I explicitly specify Int
as shown below如果我明确指定Int
,它也可以正常工作,如下所示
// 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))
Question 1问题 1
Is it possible to get below working?是否有可能低于工作?
println(exec((p1, p2) => p1 == p2, 10, 10))
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
.例如,通过使用隐式、不同地定义exec
或使用其他方式使编译器能够推断 p1 和 p2 的类型,这样它就不会因missing parameter type
而失败。
So no explicit type hints or declared methods are used.所以没有使用明确的类型提示或声明的方法。
Question 2问题2
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
)?编译器如何推断eq
的类型以及为什么它适用于p1 == p2
或p1 != p2
等表达式但p1 >= p2
失败(错误是value >= is not a member of type parameter whatever
)?
Question 1 Is it possible to get below working?问题1 是否有可能低于工作?
If you can rewrite exec
like this:如果您可以像这样重写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.然后,编译器将已经知道 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.这是一个常见的习惯用法,先放置普通参数,然后在单个参数组上放置 function。
How does compiler infer types for eq and why it works for expressions like p1 == p2 or p1 != p2 but fails for p1 >= p2编译器如何推断 eq 的类型以及为什么它适用于 p1 == p2 或 p1 != p2 等表达式但对于 p1 >= p2 失败
Because, Scala has universal equality (which is one of the things people most criticize of the language, but it was necessary for Java interop).因为, Scala具有普遍平等(这是人们最批评该语言的事情之一,但对于Java互操作来说是必要的)。
So, you can always compare two objects of any class for equality.因此,您始终可以比较任何 class 的两个对象是否相等。
That is because equality is defined in the Any superclass as follows.这是因为在Any超类中定义了相等性,如下所示。
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 theOrdering
- typeclass .如果你愿意,你可能想写一个通用的 function 只要有这种类型的订单,它就适用于任何类型,你可能对Ordering
- typeclass感兴趣。
But that is topic for another question.但这是另一个问题的主题。
Scala 3 (dotty) will be able to infer the types in exec
without having to rely on multiple parameter lists to help inference Scala 3(dotty)将能够推断exec
中的类型,而无需依赖多个参数列表来帮助推断
scala> def exec[T](f: (T, T) => Boolean, p1: T, p2: T) = f(p1, p2)
| exec((p1, p2) => p1 == p2, 10, 10)
def exec[T](f: (T, T) => Boolean, p1: T, p2: T): Boolean
val res0: Boolean = true
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.