Scala Overview
Scala is object-oriented
- Scala is a pure object-oriented language in the sense that every value is an object. Types and behavior of objects are described by classes and traits. Classes are extended by subclassing and a flexible mixin-based composition mechanism as a clean replacement for multiple inheritance.
- Every user-defined class in Scala implicitly extends the trait scala.ScalaObject.
- If Scala is used in the context of a Java runtime environment, then scala.AnyRef corresponds to java.lang.Object.
Scala is Functional
- Scala is also a functional language in the sense that every function is a value.
- Scala provides a lightweight syntax for defining anonymous functions, it supports higher-order functions, it allows functions to be nested, and supports currying.
- Scala‘s case classes and its built-in support for pattern matching model algebraic types used in many functional programming languages.
Anonymous Function Syntax
- eg:
(x: Int) => x + 1This is a shorthand for the following anonymous class definition:
new Function1[Int, Int] { def apply(x: Int): Int = x + 1 }
- It is also possible to define functions with multiple parameters:
(x: Int, y: Int) => "(" + x + ", " + y + ")"
- or even with no parameter:
() => { System.getProperty("user.dir") }
Higher-Order Functions
- Higher-order functions are those who can take functions as parameters, or whose result is a function.
- Eg: Function apply which takes another function f and a value v and applies function f to v:
def apply(f: Int => String, v: Int) = f(v) - A more complicated example:
class Decorator(left: String, right: String) { def layout[A](x: A) = left + x.toString() + right } object FunTest extends Application { def apply(f: Int => String, v: Int) = f(v) val decorator = new Decorator("[", "]") println(apply(decorator.layout, 7)) }
In this example, the method decorator.layout is coerced automatically to a value of type Int => String as required by method apply. Please note that the method decorator.layout is a polymorphic method(i.e. it abstracts over some of its signature types) and the Scala compiler has to instantiate its method type first appropriately.
Nested Functions
- In Scala it is possible to nest function definitions.
- Eg:
object FilterTest extends Application { def filter(xs: List[Int], threshold: Int) = { def process(ys: List[Int]): List[Int] = if (ys.isEmpty) ys else if (ys.head < threshold) ys.head :: process(ys.tail) else process(ys.tail) process(xs) } println(filter(List(1, 9, 2, 8, 3, 7, 4), 5)) }
Currying
- Methods may define multiple parameter lists. When a method is called with a fewer number of parameter lists, then this will yield a function taking the missing parameter lists as its arguments.
- Eg:
object CurryTest extends Application { def filter(xs: List[Int], p: Int => Boolean): List[Int] = if (xs.isEmpty) xs else if (p(xs.head)) xs.head :: filter(xs.tail, p) else filter(xs.tail, p) def modN(n: Int)(x: Int) = ((x % n) == 0) val nums = List(1, 2, 3, 4, 5, 6, 7, 8) println(filter(nums, modN(2))) println(filter(nums, modN(3))) }
Note that method modN is partially applied in the two filter calls; i.e. only its first argument is actually applied. The term modN(2) yields a function of type Int => Boolean and is thus a possible candidate for the second argument of function filter.
Case Classes
时间: 2024-10-09 15:41:22