Это третья статья из небольшой серии о Клейсли в реальном мире. На этот раз мы увидим, как его можно использовать для чтения и передачи конфигурации. На самом деле мы используем это в микросервисе, где параметры конфигурации считываются от пользователя, и некоторые вещи могут дать сбой, поэтому необходимо обернуть инициализацию определенных частей программного обеспечения внутри монады Try.

Этот пример в основном взят из Документации Cats Kleisli, хотя и с — с моей скромной точки зрения — дополнительными разъяснениями того, что именно делает код, и упрощен за счет удаления некоторых менее важных деталей. Кроме того, для легкого введения в Kleisli, не стесняйтесь читать мой пост Понимание Kleisli в Scala.

1–4.

Требуемые библиотеки

6–10.

Это упрощение нашей БД. Он включает в себя класс конфигурации DbConfig с необходимыми параметрами и саму БД, представленную с помощью типажа, поэтому мы можем изменить реализацию в любой момент. DBImpl.fromDbConfig пытается создать новый экземпляр БД с параметрами конфигурации.

12–16.

То же самое с Service, который представляет собой некий REST-сервис, который мы собираемся использовать в нашем приложении.

18–20.

Это наше приложение. У него есть БД и служба. Поскольку это трейты, мы можем позже решить точную реализацию.

22.

Мы определяем функцию, которая получит AppConfig и попытается инициализировать App. В зависимости от результата возвращается либо Success(App), либо Failure.

Почему здесь мы используем Kleisli, а не просто делаем что-то вроде appFromAppConfig(conf: AppConfig): Try[App] и разрешаем db и sv, вызывая их с помощью conf внутри для понимания? Что ж, это будет работать правильно, но если мы можем работать на более высоком уровне и позволить мощной системе типов Scala делать работу за нас, почему бы не воспользоваться этой возможностью?

23.

Обратите внимание, что для понимания работает на Клейсли. Прохладный!

24–25.

Здесь мы используем local. Это мощная функция, которая позволяет использовать другой тип ввода для Клейсли, если вы сообщите ему, как преобразовать этот новый тип в исходный. Здесь мы создаем анонимную функцию, которая принимает appConfig и создает DbConfig, извлекая соответствующие параметры.

28–29.

Простой пример.