如何从一个仿函数超越一个效果到一个效果超越仿函数?
How to go from an functor over an effect to an effect over the functor?
我有两种不同类型的用户;我们称它们为 BasicUser
和 EnrichedUser
。
我在具有 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
,则不需要显式类型参数。
我有两种不同类型的用户;我们称它们为 BasicUser
和 EnrichedUser
。
我在具有 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
,则不需要显式类型参数。