Foldable for tuples?
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 5.5k
- Forks
- 1.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 5
Description
Hey there.
In https://github.com/typelevel/cats/pull/3299 (I think. at least in 2.4.x) tuples gained a Foldable (among others, naturally) instance, which only considers the right-most element.
I guess I'm opening up a discussion of whether this makes any sense?
import cats.syntax._
def toList[F[_]: Foldable, A](fa: F[A]): List[A] =
Foldable[F].toList(fa)
println(toList((1,2))) // List(2)
The issue I see is I associate Foldable with "handle all values" rather than "handle a subset of a value".
How this breaks the Text type class in doobie for tuples
Onto the discussion of how I ended up looking into this. I tried to upgrade cats to 2.4.2 from 2.3.1, and it broke our code in a strange way.
We use doobie, which among other things offers a way to stream As to postgres via a (tab-separated) textual format through the Text type class.
Let's examine a derivation rule which now causes problems:
It takes a Foldable F of As and puts the As into a postgres array, again in the textual representation. Crucially, this is prioritized before the macro which composes instances for Text for for product types, which is what we used to hit.
object Text {
// ... simplified, it's really in a parent
implicit def foldableInstance[F[_]: Foldable, A](implicit ev: Text[A]): Text[F[A]] =
iterableInstance[List, A].contramap(_.toList)
}
Here is a minified example, where you can see the resolved implicits before and after
object Tester extends App {
import cats.UnorderedFoldable
import doobie.postgres.Text
def p[A: Text](a: A): Unit =
println(Text[A].encode(a))
private val tuple: (Int, Long, String) = (1, 2L, "hello")
p(tuple)
// cats 2.3.x it picked this
p(tuple)(Text.generic)
// output: 1 2 hello
// cats 2.4.x it picks this
p(tuple)(Text.foldableInstance(UnorderedFoldable.catsUnorderedFoldableInstancesForTuple3, Text[String]))
// output: {"hello"}
}
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
Review the tuple Foldable instance introduced around cats PR 3299 and reproduce the toList((1,2)) example with the Cats 2.3.x and 2.4.x behavior. Check doobie's linked Text.scala derivation around line 186 to understand the implicit-resolution impact. Done means reaching a documented decision about tuple Foldable behavior and its compatibility effects.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- api
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100