2

I have two different types of users; let's call them BasicUser and EnrichedUser.

I get a value of the Foo user type inside a container C that has a cats.Functor instance:

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

Now I'd like to map over this value (using the functor instance) to turn the contained BasicUser into an EnrichedUser user, staying in the container:

import cats.syntax.all._

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

However, enrichUser doesn't return EnrichedUser, but rather OptionT[Future, EnrichedUser], so I end up with the following type:

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

How can I get from this type to OptionT[Future, C[EnrichedUser]] (which I'll ultimately turn into a JSON-serialized Akka HTTP response)?

1 Answers1

1

If you have a Traverse[C] instance you can use 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]]

Extra: If you have -Ypartial-unification enabled you don't need the explicit type arguments.

Jasper-M
  • 14,966
  • 2
  • 26
  • 37
  • Okay, so I need to bite the bullet and add a Traverse instance to C :| Thanks :) –  Jun 01 '17 at 13:41