#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
Общие рекомендации:
- Запишите интерфейс на Java
- Реализовать интерфейс в Scala
- Используйте все, что вы написали, только через интерфейсы Java при написании кода на Java.
- Не пытайтесь напрямую использовать интерфейсы Scala при написании кода на Java.
Помните: компилятор Scala понимает Java. Java ничего не знает о Scala. Реализация интерфейсов Java в Scala тривиальна. Использование интерфейсов Scala из Java неудобно.
Комментарии:
1. да, это работает. Я немного упростил это до: TupleEx.f().apply(ы). ‘run’ не является обязательным.
2. @Alexandr Ах, действительно,
Kleisli
переопределяетapply
, просто перенаправляя его наrun
.