Я использую класс Parallel
для сбора всех ошибок проверки:
def getNonEmptyStr[M[_]](key: String)(
implicit
E: MonadError[M, Errors],
A: ApplicativeAsk[M, Params],
W: FunctorTell[M, List[String]]
): M[String] = ???
def getInt[M[_]](key: String)(
implicit
E: MonadError[M, Errors],
A: ApplicativeAsk[M, Params],
W: FunctorTell[M, List[String]]
): M[Int] = ???
def getUser[M[_], F[_]](
implicit E: MonadError[M, Errors],
R: ApplicativeAsk[M, Params],
W: FunctorTell[M, List[String]],
P: Parallel[M, F]
): M[User] =
(getNonEmptyStr("name"), getInt("age"), getNonEmptyStr("address"))
.parMapN(User)
Функция getUser
имеет два параметра типа:
M
это мой стек монадных преобразователей, F
- это некоторое аппликативное значение, двойственное к M
, но допускающее параллельное выполнение.
Затем я хочу вызвать его со следующим стеком монадного преобразователя:
type Stack[A] = EitherT[WriterT[Reader[Params, ?], List[String], ?], Errors, A]
Мне нужно указать параметр типа M
, чтобы сообщить компилятору, какой стек я использую,Но тогда я должен указать и параметр F
:
getUser[Stack, Nested[WriterT[Reader[Params, ?], List[String], ?], Validated[Errors, ?], ?]].value.run.run(params)
Это выглядит довольно уродливо.Есть ли способ позволить компилятору выводить F
?
Полный код здесь: https://gist.github.com/vkorenev/21bdd7d57e81a0752972f4bb3f45398a