如何调用使用 MTL 和 Parallel 的函数? [英] How to call a function which uses MTL and Parallel?

查看:39
本文介绍了如何调用使用 MTL 和 Parallel 的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Parallel 类型类来收集所有验证错误:

I am using Parallel type class in order to collect all validation errors:

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 函数有两个类型参数:

The getUser function has two type parameters:

  • M 是我的 monad 转换器堆栈,
  • F 是一些适用于 M 但允许并行执行的应用程序.
  • M is my monad transformer stack,
  • F is some applicative which is dual to M but allows parallel execution.

然后我想用以下 monad 转换器堆栈调用它:

Then I want to call it with the following monad transformer stack:

type Stack[A] = EitherT[WriterT[Reader[Params, ?], List[String], ?], Errors, A]

我需要指定 M 类型参数来告诉编译器我正在使用哪个堆栈.但是我还必须指定 F 参数:

I need to specify the M type parameter to tell the compiler which stack I am using. But then I have to specify the F parameter as well:

getUser[Stack, Nested[WriterT[Reader[Params, ?], List[String], ?], Validated[Errors, ?], ?]].value.run.run(params)

这看起来很丑.有没有办法让编译器推断 F?

This looks pretty ugly. Is there any way to let compiler infer F?

完整代码在此:https://gist.github.com/vkorenev/21bdd7d57e283a4a557e89f40f45398a>

Full code is here: https://gist.github.com/vkorenev/21bdd7d57e81a0752972f4bb3f45398a

推荐答案

可以使用 cats-par 库或添加辅助 Parallel1 类型类作为建议 此处.

It is possible to either use cats-par library or to add an auxiliary Parallel1 type class as suggested here.

然后 getUser 将只需要一个类型参数:

Then getUser will need only one type parameter:

def getUser[M[_]](
    implicit
    E: MonadError[M, Errors],
    R: ApplicativeAsk[M, Params],
    W: FunctorTell[M, List[String]],
    P: Parallel1[M]
): M[User] = {
  import P._
  (getNonEmptyStr("name"), getInt("age"), getNonEmptyStr("address")).parMapN(User)
}

希望 cats 中可以添加其中一个修复程序.

Hopefully, one of the fixes will be added to cats.

这篇关于如何调用使用 MTL 和 Parallel 的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆