In Chapter 9 of Programming In Scala, there is an example method like this:
def twice(op: Double => Double, x: Double) = op(op(x))
The author said in the book:
The type of op in this example is Double => Double, which means it is a function that takes one Double as an argument and returns another Double.
I don't understand what is "Double => Double" here, in previous chapters, where "=>" appears only means function literal, and never wrote like this "Type => Type", because according to Scala function literal syntax definition, the right part of function literal is the function body, how can a function body be "Double" ?
Arrow is a type class for modeling composable relationships between two types. One example of such a composable relationship is function A => B ; other examples include cats. data. Kleisli (wrapping an A => F[B] , also known as ReaderT ), and cats.
=> is syntactic sugar for creating instances of functions. Recall that every function in scala is an instance of a class. For example, the type Int => String , is equivalent to the type Function1[Int,String] i.e. a function that takes an argument of type Int and returns a String .
In Scala, Double is a 64-bit floating point number, which is equivalent to Java's double primitive type. The >(x: Double) method is utilized to return true if this value is greater than x, false otherwise.
In Scala, a higher-order function is a function which takes another function as an argument. A higher-order function describes "how" the work is to be done in a collection. Let's learn the higher order function map. The map applies the function to each value in the collection and returns a new collection.
Because it has two usages.
First, you could use => to define function literal.
scala> val fun = (x: Double) => x * 2 fun: (Double) => Double = <function1> scala> fun (2.5) res0: Double = 5.0
It's pretty easy. But the question here is, what type fun
is? It is a "function that takes a Double as an argument and return a double", right?
So how could I annotate fun with its type? That is (Double) => (Double)
. Well, the previous example could be rewritten to:
scala> val fun: Double => Double = (x: Double) => x * 2 fun: (Double) => Double = <function1> scala> fun (2.5) res1: Double = 5.0
OK, then what does the following code do?
def twice(op: Double => Double, x: Double) = op(op(x))
Well, it tells you that op is a (Double => Double)
, which means it needs a function which takes a Double and return a Double.
So you could pass the previous fun
function to its first argument.
scala> def twice(op: Double => Double, x: Double) = op(op(x)) twice: (op: (Double) => Double,x: Double)Double scala> twice (fun, 10) res2: Double = 40.0
And it will be equivalent to replacing op
with fun
, and replace x
with 10
, that is fun(fun(10))
and the result will be 40.
In addition to separating the parameter list from the function body in a function literal, the double arrow can be used as syntactic sugar for a FunctionN type:
T => R
means Function1[T, R]
(T1, T2) => R
means Function2[T1, T2, R]
...
In your example, this means that op
is a function that takes a Double and returns a Double (as the author explained).
As another example, it's possible to write
// declare len as a function that takes a String and returns an Int, // and define it as returning the length of its argument val len: String => Int = { _.length } // or, a more verbose version that uses '=>' in both ways val len: String => Int = { (s: String) => s.length } len("apple") // returns 5
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With