absorption/lifting typeclass to generalize a few concepts
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 5.5k
- Forks
- 1.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 5
Description
We have FunctorFilter and TraverseFilter. I have in the past proposed a generalization (FunctorFlatten, later AlternativeFlatten: #1337).
But it seems to me the above are actually doing something like:
trait Absorbs[F[_], G[_]] {
def absorb[A](f: F[G[A]]): F[A]
}
In the case of FunctorFilter[F] what you are saying is you have Functor[F] and Absorbs[F, Option]. In the case of FunctorFlatten what you are saying is that you have Functor[F] and Absorbs[F, G] for all G[_]: Foldable. You can imagine Absorb[F, Eval] when you have Defer[F] and Functor[F].
Now, as stated above, Absorbs is lawless. It is just describing shapes. But there is way to talk about laws depending on what constraints to put on G[_]. Consider the case of FunctorFlatten[F] where we are talking about Absorbs[F, Option].
I think the law here is monadic bind on option:
val f1: A0 => Option[A1] = ???
val f2: A1 => Option[A2] = ???
//...
val f: F[A0] = ???
f.map(f1).map(_.flatMap(f2)).absorb[G] == fa.map(f1).absorb[G].map(f2).absorb[G]
Indeed, all of the examples I'm discussion are about absorbing a Monad: Option, List, Vector. So, let's say the first parameter F[_]: Functor and the second is a monad: G[_]: Monad then I think we can cover four cases: FunctorFilter, TraverseFilter, AlternativeFlatten, and see below LiftIO.
So, a bit more flushed out:
trait Absorbs[F[_], G[_]] {
def functorF: Functor[F]
def monadG: Monad[G]
def absorb[A](f: F[G[A]]): F[A]
def absorbMap[A, B](f: F[A])(fn: A => G[B]): F[B] =
absorb(functorF.map(f)(fn))
}
I think these things compose: if you have Absorbs[F, G1] and Absorbs[G1, G2] then you have Absorbs[F, G2]. This is the case if the inner parameter is a monad and the outer a functor, then you can go: F[G2[A]] => F[G1[G2[A]] using map and G1.pure, then use map(_.absorb)to getF[G1[A]]then finally the first absorb to get toF[A]`.
To recall the motivation of #1337, scalding TypedPipe can absorb foldable things: Absorbs[TypedPipe, List]. Similarly with spark: Absorbs[RDD, List] Absorbs[Dataset, List].
Lastly, I will note that LiftIO[F] is quite similar to Absorb[F, IO] (if you have IO[A] you can use pure to get F[IO[A]] then absorb to F[A]. So, Applicative[F] and Absorb[F, IO] as sufficient for LiftIO[A].
Note, all the list-like collections can absorb each other: Absorb[List, Vector], Absorb[List, Chain], etc... and of course they can absorb options: Absorb[List, Option]....
Lastly, I will note that LiftIO[F] is quite similar to Absorb[F, IO] (if you have IO[A] you can use pure to get F[IO[A]] then absorb to F[A]. So, Applicative[F] and Absorb[F, IO] as sufficient for LiftIO[A].
For all Monads, Absorb[F, F] can be defined.
Note, all the list-like collections can absorb each other: Absorb[List, Vector], Absorb[List, Chain], etc... and of course they can absorb options: Absorb[List, Option]....
This is an idea I've been thinking a bit here and there. There may be prior literature on it (I may have even seen it and forgot it, if so I apologize for forgetting). It seems to me to be a bit more principled than what we have now: a few ad-hoc examples of absorption.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the existing FunctorFilter, TraverseFilter, AlternativeFlatten, and LiftIO abstractions, along with the related discussion in #1337. The issue proposes a new Absorbs typeclass and laws, but does not identify implementation files or tests. Done would require an agreed design, implementation scope, and corresponding validation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100