Open LukaJCB opened 6 years ago
can you give some examples of the type class? (i.e. some instances).
Oh sorry, I forgot to link the actual article: https://mpilquist.github.io/blog/2015/06/18/invariant-shadows/
Hi, just to add a concrete use case I found:
import cats.implicits._
import cats.{Applicative, Monad}
import scala.concurrent.{ExecutionContext, Future}
trait Repository[F[_], T, K] {
implicitly[Applicative[Option]]
def transform[T2](mapF: T => F[T2], contraMapF: T2 => T)(implicit F: Monad[F], ec: ExecutionContext): Repository[F, T2, K] = {
val self = this
new Repository[F, T2, K] {
override def store(record: T2): Future[F[Unit]] = self.store(contraMapF(record))
override def queryKey(key: K): Future[F[Option[T2]]] =
self.queryKey(key).map(_.flatMap(_.traverse(mapF)))
}
}
def store(record: T): Future[F[Unit]]
def queryKey(key: K): Future[F[Option[T]]]
}
We often have a more raw representation of a record for storing that is then transformed into a friendlier representation after some validation. But going back from the friendlier format to the raw cannot fail. Also found similar needs for encoder/decoder representations.
Hope it helps drive this 🙂
Is there a version of this which uses
def iflatMap[A, B](fa: F[A])(f: A => F[B])(g: B => F[A]): F[B]
?
I would think that iflatMap would adjust both f
and g
equally, to return an F
.
I came across the need for one recently and I think they can be fairly useful sometimes. I've sketched out something based on @mpilquist's article
I think all of our current instances of
InvariantMonoidal
can also beInvariantMonad
s. I think it comes up enough to be useful in cats-core, but one could also envision this belonging into something like the proposedcats-more
.