使用多态函数作为参数 [英] Using polymorphic function as a parameter

查看:94
本文介绍了使用多态函数作为参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数exec,该函数接受3个参数,并将作为第一个参数传递的函数f应用于其他两个参数-p1p2.

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 == p2p1 != 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆