我必须定义一个二阶函数,它将一个函数作为参数。
在我的应用程序中,输入函数可能有任何输入类型,但输出类型必须是指定的类型(假设为Int,无关紧要)。
我定义了二阶函数:
def sof(f : (Any => Int) ) = {...}
现在,如果我有一个函数f : Int => Int
,我会调用:
sof(f)
我明白了:
found : Int => Int
required: Any => Int
我想我误解了Any类型的含义。
我怎样才能让它发挥作用?
答案 0 :(得分:4)
Scala中的函数参数是逆变的。这意味着Int => Int
不是Any => Int
的子类型,反之亦然。想象一下:您将一个String传递给Any => Int
函数(实际上由Int => Int
函数实现)。 Int => Int
如何处理String参数?
答案 1 :(得分:2)
你不应该在那里使用Any
,但是类型参数如:
def sof[A](f: A => Int) = {...}
但是我不认为你可以用这种方法做很多事情。可能你会想要这样的东西:
def sof[A](a: A)(f: A => Int) = f(a)
// usage example
val x = sof("hello")(_.size * 2) // the result is 10
// you can also partially apply it to obtain other functions
val sizeDoubler: String => Int = sof(_)(_.size * 2)
val helloDoubleSize = sizeDoubler("hello") // the result is 10
通过这种方式,您可以将任何类型传递给sof
,而且您可以让编译器发出任何奇怪的行为。使用Any
会失去这种能力。
最后注意:如果我用来将两个参数(A
值和A => Int
函数)传递给方法的语法看起来很奇怪,那就是称为currying。如果你谷歌它,你会发现许多关于它的好文章。