Как внедрить зависимости через Scala Reader из кода Java

#scala #dependency-injection #scala-cats #scala-java-interop #reader-monad

#scala #внедрение зависимостей #scala-кошки #scala-java-interop #считыватель-монада

Вопрос:

Вот служба зависимостей:

   public class Service1 {}
  

Код Scala, который использует его через Reader:

 object TupleEx {
  type FailFast[A] = Either[List[String], A]
  type Env[A] = ReaderT[FailFast, Service1, A]

  import cats.syntax.applicative._
  import cats.instances.either._

  def f:Env[Int] = 10.pure[Env]
}
  

Java-тест, в котором я пытаюсь внедрить Service1:

   @Test
  public void testf() {
    Service1 s = new Service1();
    TupleEx.f().run(s);
  }
  

Я получаю исключение:

Ошибка: (10, 16) java: метод, запущенный в классе cats.data.Kleisli не может быть применен к заданным типам; требуется: аргументы не найдены: com.savdev.Service1 причина: списки фактических и формальных аргументов отличаются по длине

Хотя в Scala я мог бы запустить его как:

 TupleEx.f().run(s);
  

Ответ №1:

Попробуйте:

 TupleEx.f().run().apply(s);
  
  • run() является ли метод «getter» val внутренним Kleisli
  • apply() это то, что обычно скрыто синтаксическим сахаром Scala

Общие рекомендации:

  1. Запишите интерфейс на Java
  2. Реализовать интерфейс в Scala
  3. Используйте все, что вы написали, только через интерфейсы Java при написании кода на Java.
  4. Не пытайтесь напрямую использовать интерфейсы Scala при написании кода на Java.

Помните: компилятор Scala понимает Java. Java ничего не знает о Scala. Реализация интерфейсов Java в Scala тривиальна. Использование интерфейсов Scala из Java неудобно.

Комментарии:

1. да, это работает. Я немного упростил это до: TupleEx.f().apply(ы). ‘run’ не является обязательным.

2. @Alexandr Ах, действительно, Kleisli переопределяет apply , просто перенаправляя его на run .