The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

312748 (5) [Avatar] Offline
In exercise 6.2, we are asked to implement AccountService using Task instead of Future. The hint mentions that you don't need monad transformers but I can't seem to figure out how to achieve this.

For example, if we modify our Valid[A] type to the following:

type Valid[A] = Task[NonEmptyList[String] \/ A]
type AccountOperation[A] = Kleisli[Valid, AccountRepository, A]

Then the methods in our service class will return tasks of type Task[NonEmptyList[String] \/ A] and in order to work with these values without executing them, we still have to resort to a nested for-yield. Well, either that or implement a monadic transformer like with the Future example.

The other alternative that I was thinking was to implement the Valid type as:

type Valid[A] = Task[A]

and then return all of our errors as exceptions within the Task:

Task {
  repo.query(no) match {
    case \/-(x) => x
    case -\/(errors) => throw new Exception(errors.mkString(","))

This, however, did not seem very functional as it relies on exceptions. Am I missing something? Is our implementation really simpler when we use Task instead of Future?