Scala в примерах: различия между версиями

Содержимое удалено Содержимое добавлено
Начат перевод главы 5.
Строка 571:
'''Упражнение 4.6.1''' Придумайте хвостово-рекурсивную версию функции <tt>factorial</tt>.
 
= Функции первого класса =
 
Функции в Scala являются "значениями первого класса". Как любые другие значения, их можно передавать как параметры и возвращать как результаты. Функции, которые принимают другие функции в качестве параметров или возвращают их как результаты, называются ''функциями высшего порядка''. Эта глава представляет функции высшего порядка и показывает гибкий механизм для составления программ, которые они реализуют.
 
Для мотивации рассмотрим следующие три задания.
 
1. Написать функцию для суммирования всех целых чисел между двумя данными числами <tt>a</tt> и <tt>b</tt>:
 
<font size=3><syntaxhighlight lang=Scala>
def sumInts(a: Int, b: Int): Int =
if (a > b) 0 else a + sumInts(a + 1, b)
</syntaxhighlight></font>
 
2. Написать функцию для суммирования квадратов всех целых чисел между двумя данными числами <tt>a</tt> и <tt>b</tt>:
 
<font size=3><syntaxhighlight lang=Scala>
def square(x: Int): Int = x * x
def sumSquares(a: Int, b: Int): Int =
if (a > b) 0 else square(a) + sumSquares(a + 1, b)
</syntaxhighlight></font>
 
3. Написать функцию для суммирования степеней двойки ''2<sup>n</sup>'' для всех целых чисел между двумя данными числами <tt>a</tt> и <tt>b</tt>:
 
<font size=3><syntaxhighlight lang=Scala>
def powerOfTwo(x: Int): Int = if (x == 0) 1 else 2 * powerOfTwo(x - 1) def sumPowersOfTwo(a: Int, b: Int): Int =
if (a > b) 0 else powerOfTwo(a) + sumPowersOfTwo(a + 1, b)
</syntaxhighlight></font>
 
Все эти функции являются сущностями <math>\sum\limits_a^b f(n)</math> для разных значений ''f''. Мы можем выделить общий шаблон, определив функцию <tt>sum</tt>:
 
<font size=3><syntaxhighlight lang=Scala>
def sum(f: Int => Int, a: Int, b: Int): Int =
if (a > b) 0 else f(a) + sum(f, a + 1, b)
</syntaxhighlight></font>
 
Тип <tt>Int => Int</tt> — это тип функции, которая принимает аргумент типа <tt>Int</tt> и возвращает результат типа <tt>Int</tt>. Так что <tt>sum</tt> — функция, берущая в качестве параметра другую функцию. Другими словами, <tt>sum</tt> — функция высшего порядка.
 
Используя <tt>sum</tt>, мы можем сформулировать три суммирующие функции так:
 
<font size=3><syntaxhighlight lang=Scala>
def sumInts(a: Int, b: Int): Int = sum(id, a, b)
def sumSquares(a: Int, b: Int): Int = sum(square, a, b)
def sumPowersOfTwo(a: Int, b: Int): Int = sum(powerOfTwo, a, b)
</syntaxhighlight></font>
 
где
 
<font size=3><syntaxhighlight lang=Scala>
def id(x: Int): Int = x
def square(x: Int): Int = x * x
def powerOfTwo(x: Int): Int = if (x == 0) 1 else 2 * powerOfTwo(x - 1)
</syntaxhighlight></font>
 
== Анонимные функции ==
== Каррирование ==
Строка 963 ⟶ 1015 :
== Функции ==
 
Scala — функциональный язык в том смысле, что функции — значения первого порядкакласса. Scala также объектно-ориентированный язык в том смысле, что каждое значение является объектом. Из этого следует, что функции в Scala являются объектами. Например, функция из типа <tt>String</tt> в тип <tt>Int</tt> представлена экземпляром трейта <tt>Function1[String, Int]</tt>. Трейт <tt>Function1</tt> определен так:
 
<font size=3><syntaxhighlight lang=Scala>
Строка 1004 ⟶ 1056 :
</syntaxhighlight></font>
 
Здесь создание объекта <tt>'''new''' Function1[Int, Int]{ … }</tt> представляет собой сущность ''анонимного класса''. Оно сочетает создание новойнового объекта <tt>Function1</tt> с реализацией метода <tt>apply</tt> (который абстрактен в <tt>Function1</tt>). Эквивалентно, но более многословно можно было бы использовать локальный класс:
 
<font size=3><syntaxhighlight lang=Scala>