buildo / nozzle

MIT License
0 stars 1 forks source link

[Controllers] eitherT interface enhancement #17

Open calippo opened 8 years ago

calippo commented 8 years ago

requirements

We want to avoid people write things like

for {
  a <- eitherT(something.map(_.point[CtrlFlow]))
  b <- eitherT(something.point[Future])
}

At the same time, we don't want to hide monad transformers too much. We'd like to be clear why in user <- eitherT(Future(\/-(user))) the type of user is User and not \/[_, User].

specs

proposed solution

Me and @federico-pellegatta decided to introduce in a project these helpers to avoid people to get mad finding the right EitherT method

object CtrlHelper {
  def validationEitherT(validation: CtrlFlow[Unit])(implicit executionContext: ExecutionContext): FutureCtrlFlow[Unit] = EitherT.fromDisjunction(validation)
  def actionEitherT(action: Future[Unit])(implicit executionContext: ExecutionContext): FutureCtrlFlow[Unit] = EitherT.right(action)
  def eitherT[T](obj: Future[CtrlFlow[T]])(implicit executionContext: ExecutionContext): FutureCtrlFlow[T] = EitherT.eitherT(obj)
}

observations about the proposed solution:

If you're going for an alias to keep scalaz out of the radars, may I suggest something that doesn't end with eitherT?

gabro

EitherT name is fine, is not bound to scalaz and we are not trying to hide what we're doing. My problem is that EitherT.fromDisjunction and EitherT.right are too hidden in scalaz code. In other project we are not using EitherT.fromDisjunction and EitherT.right even though they would be useful. We just couldn't easily find them.

That's why we added an alias with a meaningful signature in the project.

claudio

My point is

validationEitherT[A] returns a FutureCtrlFlow[A], i.e. the name of the method leaks the underlying abstraction.

What about toFutureCtrlFlow (possibly overloaded)

gabro

That was actually our first experiment. I was kind of ok with that, but we came across a couple of problems: 1) we like to know what method we're using, especially when a high level of magic is involved 2) overload method clashes on Future[_] -> FutureCtrlFlow

We didn't implement generic methods (with the exception of eitherT[T]). validationEitherT and actionEitherT are there only for FutureCtrlFlow[Unit]. We are calling validation something that returns \/[SomeError, Unit] and action something that returns Future[Unit].

It was meant to be easier for the developer to understand, if it was not clear to you we are probably doing something wrong.

claudio

calippo commented 8 years ago

@utaal moved discussion here as promised :) @gabro @federico-pellegatta let's continue the discussion here.