Функцию op можно выделить в отдельный функциональный параметр у foldLeft, благодаря такому выделению становится возможен более элегантный стиль передачи анонимной функции в метод. Без такого выделения код выглядел бы следующим образом:
numbers.foldLeft(0, {(m: Int, n: Int) => m + n})
Обратите внимание, что использование отдельного функционального параметра позволяет нам использовать автоматическое выведение типа для него, что делает код еще более кратким, это было бы невозможно без каррирования.
numbers.foldLeft(0)(_ + _)
Если в утверждении numbers.foldLeft(0)(_ + _) зафиксировать отдельный параметр z, мы получим частично определенную функцию, которую можно переиспользовать, как показано ниже:
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val numberFunc = numbers.foldLeft(List[Int]())_ // z = Empty.List[Int]
val squares = numberFunc((xs, x) => xs:+ x*x)
print(squares.toString()) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100)
val cubes = numberFunc((xs, x) => xs:+ x*x*x)
print(cubes.toString()) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000)
foldLeft и foldRight может быть использован в любой из следующих вариаций,
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
numbers.foldLeft(0)((sum, item) => sum + item) // Общая Форма
numbers.foldRight(0)((sum, item) => sum + item) // Общая Форма
numbers.foldLeft(0)(_+_) // Форма с каррированием
numbers.foldRight(0)(_+_) // Форма с каррированием
Чтоб указать что параметр используется неявно (implicit) необходимо задавать несколько списков параметров. Примером может служить следующее:
def execute(arg: Int)(implicit ec: ExecutionContext) = ???
17. Что такое анонимная функция?
Анонимная функция в программировании — особый вид функций, которые объявляются в месте использования и не получают уникального идентификатора для доступа к ним
Scala анонимные функции, определенные в синтаксисе очень просто, стрелка слева находится список параметров, право является тело функции, параметр типа опущен, вывод типов Scala будет вывести аргументы типа. После использования анонимных функций, наш код более кратким.
Следующее выражение определяет принимает входной параметр типа Int анонимной функции:
var inc = (x:Int) => x+1
Объем анонимной функции очень мал, обычно анонимная функция используется как параметр другой функции.
18. Что такое функции высшего порядка?
Функция высшего порядка - это функция, принимающие функции в качестве аргументов или возвращающая функцию как результат.
Такое возможно поскольку функции являются объектами первого класса в Scala.
Одним из наиболее распространенных примеров функции высшего порядка является функция map, которая доступна в коллекциях Scala.
val salaries = Seq(20000, 70000, 40000)
val doubleSalary = (x: Int) => x * 2
val newSalaries = salaries.map(doubleSalary) // List(40000, 140000, 80000)
doubleSalary - это функция, которая принимает один Int x и возвращает x * 2. В общем случае, кортеж (список имен в скобках) слева от стрелки => - это список параметров, а значение выражения следует справа. Это же значение возвращается в качестве результата. В строке 3 к каждому элементу списка зарплат (salaries) применяется функция doubleSalary.
Чтобы сократить код, мы можем сделать функцию анонимной и передать ее напрямую в качестве аргумента в map:
val salaries = Seq(20000, 70000, 40000)
val newSalaries = salaries.map(x => x * 2) // List(40000, 140000, 80000)
Одной из причин использования функций высшего порядка является сокращение избыточного кода.
19. В чем разница между var и val?
в Scala есть два типа переменных:
val создает неизменяемую переменную (как finalв Java)
var создает изменяемую переменную
В Scala общее правило состоит в том, что вы всегда должны использовать val поле, если нет веской причины не делать этого.
Это простое правило
(а) делает ваш код более похожим на алгебру
(б) помогает вам начать путь к функциональному программированию, где все поля неизменяемы.
20. Что такое some и none?
Опция – это коллекция элементов заданного типа.
Для создания Option используется запись следующего вида:
def findDeveloper(key: String): Option[Developer];
Данный метод вернёт Some[Developer] если запись будет найдена в указанной коллекции, либо None – если нет.
Some и None являются дочерними элементами Option
21. Как можно форматировать строки?
https://docs.scala-lang.org/overviews/core/string-interpolation.html
https://www.geeksforgeeks.org/scala-format-and-formatted-method/
22. Типы литералов в Scala.
Любое постоянное значение, которое может быть присвоено переменной, называется литералом / константой. Литералы представляют собой последовательность символов, используемых для описания постоянного значения в коде.
целочисленные
с плавающей точкой
булевы. Логические литералы допускают только два значения: истина и ложь , которые являются членами типа Boolean.
строковые
многострочные. Многострочные строковые литералы также являются сериями символов, но имеют несколько строк (в тройных ковычках)
символьные. символьные литералы являются символами Uni-кода
23. Чем отличается List и Array?
Массив является изменяемым, что означает, что вы можете изменять значения каждого индекса, в то время как Список (по умолчанию) неизменяем, что означает, что каждый раз, когда вы вносите изменения, создается новый список.
Для характеристик производительности массив быстрее с произвольным доступом к элементам, в то время как Список быстрее при добавлении (добавлении) новых элементов.
24. Является ли язык Scala статически типизированным?
25. Что такое статически типизированный язык и что такое динамически типизированный язык?
Статические языки проверяют типы в программе во время компиляции, еще до запуска программы. Любая программа, в которой типы нарушают правила языка, считается некорректной.
Каждое выражение в статически типизированном языке относится к определенному типу, который можно определить без запуска кода.
Одни статически типизированные языки требуют обозначать тип. Другие могут определить тип автоматически.
Не нужно запускать программу чтобы понять, что существует проблема.
Динамически типизированные языки не требуют указывать тип, но и не определяют его сами. Типы переменных неизвестны до того момента, когда у них есть конкретные значения при запуске.
Говорят, что значения в динамических языках обладают типом, но переменные и функции — нет.
Большинство динамических языков выдадут ошибку, если типы используются некорректно. При использовании динамически типизированных языков даже простая ошибка вида "a" + 1 может возникнуть в боевом окружении. Статические языки предотвращают такие ошибки, но, конечно, степень предотвращения зависит от мощности системы типов.
Статические и динамические языки построены на фундаментально разных идеях о корректности программ. В динамическом языке "a" + 1 это корректная программа: код будет запущен и появится ошибка в среде исполнения. Однако, в большинстве статически типизированных языков выражение "a" + 1 — это не программа: она не будет скомпилирована и не будет запущена. Это некорректный код, так же, как набор случайных символов !&%^@*&%^@* — это некорректный код.
26. В чем разница между статически типизированными и динамически типизированными языками?
https://fooobar.com/questions/99292/what-is-the-difference-between-statically-typed-and-dynamically-typed-languages
https://habr.com/ru/post/308484/
https://proglib.io/p/literacy-project-type-checking
27. Является ли Scala чистым языком ООП? Является ли Java чистым языком ООП?
Scala является чистым объектно-ориентированным языком в том смысле, что все является объектом, включая числа или функции. В этом отношении он отличается от Java, поскольку Java различает примитивные типы (такие как boolean и int) и ссылочные типы.
28. Как и класс Java java.lang.Object, что является суперклассом всех классов в Scala?
Класс Any является корнем иерархии классов Scala. Каждый класс в среде выполнения Scala прямо или косвенно наследуется от этого класса.
Scala Standard Library 2.13.5 - scala.Any (scala-lang.org)
29. Что такое модификатор доступа по умолчанию в Scala? Есть ли у Scala ключевое слово public?
Все поля классов по умолчанию имеют модификатор public.
Ссылка №1
Ссылка №2
30. Что такое REPL в Scala? Какая польза от Scala REPL? Как получить доступ к Scala REPL из командной
строки?
Scala REPL - это инструмент ( scala ) для оценки выражений в Scala.
Команда scala выполнит исходный сценарий, заключив его в шаблон, а затем скомпилировав и выполнив полученную программу.
В интерактивном режиме REPL считывает выражения в приглашении, помещает их в исполняемый шаблон, а затем компилирует и выполняет результат.
Предыдущие результаты автоматически импортируются в область текущего выражения по мере необходимости.
К полезным функциям REPL относятся:
IMain REPL обязан $intp.
последнее исключение REPL связано с lastException.
используйте вкладку для завершения.
используйте, //print<tab>чтобы показать типизированные обессахаривания.
используйте :help для списка команд.
используйте :load для загрузки файла ввода REPL.
используйте :paste для ввода класса и объекта в качестве сопутствующих.
используйте, :paste -raw чтобы отключить перенос кода, чтобы определить пакет.
использовать :javap для проверки артефактов класса.
использовать -Yrepl-outdir для проверки артефактов класса с помощью внешних инструментов.
используйте :power для входа в режим мощности и импорта компонентов компилятора.
использовать :settings для изменения настроек компилятора; некоторые настройки требуют :replay.
используйте :replay для воспроизведения сеанса с измененными настройками.
Примечания по реализации:
пользовательский код может быть заключен либо в объект (чтобы код запускался во время инициализации класса), либо в класс (чтобы код выполнялся во время создания экземпляра). Переключатель есть -Yrepl-class-based.
каждая строка ввода компилируется отдельно.
зависимости от предыдущих строк включаются автоматически сгенерированным импортом.
неявным импортом scala.Predefможно управлять путем ввода явного импорта.
31. Как мы реализуем циклы функционально? В чем разница между циклами в стиле ООП и ФП?
Функционально циклы мы реализуем при помощи рекурсии.
В ООП вычисление описывается в виде инструкций, изменяющих состояние вычислителя, поэтому цикл в ООП выполняет группы инструкций при помощи инструкции while или for
А в функциональном программировании модель вычислений не использует понятие изменяемого состояния, поэтому в ФП нет циклов, поскольку нет различий между итерациями
32. Что такое «Application» в Scala или «Scala Application»? Что такое «App» в Scala? Какая польза от App?
33. Поддерживает ли Scala перегрузку операторов?
в Scala нет перегрузки операторов, так как нет операторов (как сущностей отличных от методов). Есть методы с символическими (операторными) именами вида '+', '/', '::', '<~' и префиксная/инфиксная/посфиксная форма записи. (https://habr.com/ru/company/golovachcourses/blog/255631/)
34. В чем разница между «If..Else» в Java и «If..Else» в Scala?
if-else в Scala позволяет выбирать между двумя альтернативами. Синтаксис похож на if-else в Java. Но тогда как if-else в Java можно использовать только для альтернативных утверждений, Scala позволяет использовать тот же синтаксис для выбора между двумя выражениями. Поэтому в Scala if-else служит также для замены тернарного оператора Java (… ? … : ….)
35. В чем разница между функцией и методом в Scala?
Конкретные различия сводятся к следующему
1. Методы не могут существовать как отдельные выражения (кроме методов с пустыми параметрами), в то время как функции могут.
2. Функция должна иметь список параметров, а метод не может иметь список параметров
3. Имя метода является вызовом метода, а имя функции представляет только сам объект функции
4. Параметр передачи по сути является методом
Функция – это блок кода, который выполняет определённую задачу. Обычно, бизнес проблема разбивается на отдельные задачи, для решения которых, создаются функции.
Метод, в Scala, это часть класса, а функция – это отдельный объект, который может быть присвоен какой-то переменной. Т.е. метод – это функция, которая объявлена элементом класса.
36. Сколько классов можно определить в исходном файле Scala? Java?
В файле scala можно объявить любое количество как обычных классов, так и вложенных , а в java можно объявить только один главный класс и множество вложенных
37. Укажите некоторые ключевые слова, которые используются Java и не требуются в Scala? Почему Scala не требует их?
Ну, например слово return в java. Оно используется для возвращения значения из метода. А в scala, не требуется писать return,чтобы вернуть нужное значение, потому что последнее выражение в теле автоматически становится возвращаемым значением метода.
Также в java есть слово void. Его не используют в scala, потому что в scala все является выражением , что означает, что все возвращает значение. Это одна из причин, почему Scala имеется тип Unit вместо типа void - потому что даже вещи, которые были бы void в Java, должны возвращать значение в Scala.
38. Что такое побочный эффект?
По сути, побочный эффект — любое действие, которое наблюдается за пределами функции или выражения помимо возврата значения, например:
операция ввода-вывода,
модификация переменной (доступной за пределами области видимости),
изменение состояния объекта (наблюдаемое вне области видимости),
возбуждение исключения (которое также не обрабатывается внутри области видимости).
О функциях или выражениях, содержащих любое из вышеперечисленных действий, говорят, что они имеют побочные эффекты, в противном случае их называют «чистыми».
Почему побочные эффекты так важны? Потому что с ними порядок исполнения имеет значение. Например, два «чистых» выражения, (связанных с соответствующими значениями):
val x = 1 + 2
val y = 2 + 3
Так как они не содержат побочных эффектов (т.е. эффектов, наблюдаемых вне выражений), мы можем вычислить эти выражения в произвольном порядке — сначала x, а затем y или сначала y, а затем x — это не повлияет на корректность полученных результатов (мы можем даже закешировать результирующие значения, если того захотим). Теперь рассмотрим следующую модификацию:
val x = { print("foo"); 1 + 2 }
val y = { print("bar"); 2 + 3 }
А это уже другая история — мы не можем изменить порядок выполнения, потому что в нашем терминале будет напечатано "barfoo" вместо "foobar" (и это явно не то, чего хотелось).
39. Что такое выражения сопоставления? (Pattern matching)
40. Что такое замыкание?
41. Что такое частично применяемые функции?
42. Тестирование в Scala
43. Что такое type класс?
В Scala 3 классы типов - это просто черты с одним или несколькими параметрами типа, например:
trait Show[A]:
def show(a: A): String
Классы типов - это мощный инструмент, используемый в функциональном программировании для включения специального полиморфизма, более известного как перегрузка.
Он помогает бороться с лишними зависимостями и в то же время делать код чище.
Этот подход позволяет держать код каких-то аспектов функционирования класса отдельно от самой реализации класса. И создавать его даже не имея доступа к коду самого класса. В частности, такой подход оправдан и рекомендуем при наделении классов возможностью сериализации/десериализации в определенный формат
44. Что такое функциональная композиция?
https://habr.com/ru/post/283162/
http://espressocode.top/scala-function-composition/
https://medium.com/devschacht/charles-scalfani-so-you-want-to-be-a-functional-programmer-part-3-d1f567656158
https://java-blog.ru/osnovy/funktsionalnaya-kompozitsiya-java#:~:text=Функциональная%20композиция%20–%20это%20техника,использует%20объединенные%20функции%20внутри%20себя
45. Метод apply
46. Исключения в Scala
https://proselyte.net/tutorials/scala/exception-handling/
https://github.com/anton-k/ru-neophyte-guide-to-scala/blob/master/src/p06-error-handling.md
https://www.baeldung.com/scala/exception-handling
47. Ленивые значения
https://coderoad.wiki/19955995/Когда-использовать-ленивые-значения-в-Scala