官术网_书友最值得收藏!

  • Learn Scala Programming
  • Slava Schmidt
  • 401字
  • 2021-06-10 19:35:49

Higher-order functions

So far, we have discussed function literals and we've created a printHash function, which we used to demonstrate different forms of passing functions into methods:

scala> def printHash(hasher: String => Int)(s: String): Unit = 
println(hasher(s))
printHash: (hasher: String => Int)(s: String)Unit

The printHash takes two parameters: the hasher function and a string to hash. Or, in functional form:

scala> :type printHash _
(String => Int) => (String => Unit)

Our function is curried as it takes one argument (a String => Int function) and returns another function, String => Unit. The fact that printHash takes a function as an argument is reflected by saying that printHash is a higher order function (HOF). There is nothing else special about HOFs except the fact that one or multiple parameters are functions. They work just as normal functions, can be assigned and passed over, partially applied and be polymorphic:

def printHash[A](hasher: A => Int)(s: A): Unit = println(hasher(s))

In fact, HOFs usually apply function(s) given as parameter(s) to another parameter in some creative ways and therefore are almost always polymorphic.

Let's take another look at our printHash example. There is nothing in particular that requires a hasher function to calculate a hash; the function carried out by the hasher is independent of the logic of the printHash. Interestingly, this is the case more often than one would expect and it leads to the definition of HOF, for example:

def printer[A, B, C <: A](f: A => B)(a: C): Unit = println(f(a))

Our printing logic does not require the given function to have any specific type of an argument or result. The only limitation we need to enforce is that it is possible to call the function with the given argument, which we formulate with the type constraint C <: A. The nature of the function and an argument can also be anything, and it is common to use short neutral names when defining a HOF because of this. This is how our new definition can be used in practice:

scala> printer((_: String).hashCode)("HaHa")
2240498
scala> printer((_: Int) / 2)(42)
21

The compiler needs to know the type of the function, and therefore we need to define it as a part of the placeholder syntax. We can help the compiler by changing the order of the parameters of the function:

def printer[A, B, C <: A](a: C)(f: A => B): Unit = println(f(a))

With this definition, it will be possible to infer the C first and then use the inferred type to enforce the type of f:

scala> printer("HoHo")(_.length)
4
scala> printer(42)(identity)
42

The identity function is defined as def identity[A](x: A): A = x in the standard library.

主站蜘蛛池模板: 关岭| 贵定县| 雷山县| 永丰县| 杭锦后旗| 潞西市| 舒城县| 江城| 麻城市| 新竹市| 老河口市| 静乐县| 德阳市| 南投市| 永嘉县| 洛阳市| 绵阳市| 扎囊县| 张家口市| 克东县| 肥东县| 淮滨县| 娄底市| 夹江县| 岗巴县| 新疆| 丹棱县| 新河县| 太康县| 启东市| 铁岭市| 亳州市| 北辰区| 合阳县| 贡嘎县| 公主岭市| 公主岭市| 平山县| 新源县| 泾川县| 柳州市|