На этом шаге мы дадим краткую характеристику этой библиотеке.
В предыдущих шагах вы познакомились с инструментами функционального программирования, встроенными в стандартную библиотеку Kotlin, такими как map(), flatMap() и filter().
Kotlin - "мультипарадигмальный" язык. Это означает, что он смешивает приемы объектно-ориентированного, императивного и функционального программирования. Если вы работали со строго функциональным языком, таким как Haskell, то знаете, что он предлагает гораздо более продвинутые приемы функционального программирования, чем Kotlin.
Например, Haskell содержит тип Maybe - тип, который включает поддержку какого-то значения или ошибки. Это позволяет операциям, которые могли привести к сбою, возвращать результат этого типа. Использование типа Maybe позволяет сообщить об исключении (например, об ошибке парсинга числа), не возбуждая его. Благодаря этому отпадает необходимость использовать оператор try/catch.
Обрабатывать исключения без реализации логики try/catch, очень удобно. Некоторые представляют try/catch как форму инструкции GOTO, которая часто делает код сложным для понимания и поддержки. Многие возможности функционального программирования, доступные в Haskell, можно добавить в Kotlin через специальные библиотеки вроде Arrow.kt (https://arrow-kt.io/).
Например, библиотека Arrow.kt включает подобие типа Maybe из Haskell с именем Either. Использование Either позволяет выразить операцию, которая может закончиться сбоем, не прибегая к исключениям и не требуя использовать оператор try/catch.
В качестве примера рассмотрим функцию, которая преобразует ввод пользователя из строки в Int. Если пользователь введет допустимое число, оно будет преобразовано в значение Int, в противном случае функция выведет сообщение об ошибке.
Использование Either приводит к следующей логике:
fun parse(s: String): Either<NumberFormatException, Int> = if (s.matches(Regex("-?[0-9]+"))) { Either.Right(s.toInt()) } else { Either.Left(NumberFormatException("$s is not a valid integer.")) } val x = parse("123") val value = when(x) { is Either.Left -> when (x.a) { is NumberFormatException -> "Not a number!" else -> "Unknown error" } is Either.Right -> "Number that was parsed: ${x.b}" }
Никаких исключений, никаких блоков try/catch - простая и понятная логика.
На следующем шаге мы рассмотрим несколько заданий для самостоятельного решения.