如何从一个仿函数超越一个效果到一个效果超越仿函数?

How to go from an functor over an effect to an effect over the functor?

我有两种不同类型的用户;我们称它们为 BasicUserEnrichedUser

我在具有 cats.Functor 实例的容器 C 中获得 Foo 用户类型的值:

val basicUserF: C[BasicUser] = getBasicUser(…)

现在我想映射这个值(使用仿函数实例)将包含的 BasicUser 变成一个 EnrichedUser 用户,留在容器中:

import cats.syntax.all._

val enrichedUserF: C[EnrichedUser] = basicUserF.map(user => enrichUser(user))

然而,enrichUser 不是 return EnrichedUser,而是 OptionT[Future, EnrichedUser],所以我最终得到以下类型:

val enrichedUserThing: C[OptionT[Future, EnrichedUser]] = …

我怎样才能从这种类型变成 OptionT[Future, C[EnrichedUser]](我最终会变成 JSON-序列化的 Akka HTTP 响应)?

如果您有一个 Traverse[C] 实例,您可以使用 sequence

scala> implicit def CTraverse: Traverse[C] = ???
CTraverse: cats.Traverse[C]

scala> def sequenced = enrichedUserThing.sequence[OptionT[Future,?], EnrichedUser]
sequenced: cats.data.OptionT[scala.concurrent.Future,C[EnrichedUser]]

额外:如果您启用了 -Ypartial-unification,则不需要显式类型参数。