I am not sure how to describe this problem, so I'll just show the type signatures.
I have an instance of the following:
val x:Future[F[Future[F[B]]]] = ???
And I want an instance of:
val y:Future[F[B]] = ???
F
is a Monad, so I have the following methods:
def pure[A](a:A):F[A] = ???
def flatMap[A, B](fa:F[A], f:A => F[B]):F[B] = ???
def map[A, B](fa:F[A], f:A => B):F[B] = flatMap(fa, (a:A) => pure(f(a)))
I think the following should work, but it does not feel right:
x.flatMap { fWithFuture =>
val p = Promise[F[B]]
flatMap(fWithFuture, (futureF: Future[F[B]]) => {
p.completeWith(futureF)
pure(())
})
p.future
}
Is there a concept I'm missing?
A bit of background information. I am trying to define a function like this:
def flatMap[A, B](fa:Future[F[A]], f: A => Future[F[B]]):Future[F[B]] = ???
Maybe this is conceptually a weird thing. Any tips on useful abstractions are welcome.