typelevel / typelevel/cats

Unexpected behavior of `NonEmptyList.reduce` for tuples of lists

Open
#4,817 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Scala
Stars
5.5k
Forks
1.2k
Avg merge
2d 10h
Merged PRs (30d)
5

Description

NonEmptyList.reduce used the wrong, or at least unexpected Semigroup instance for tuples of lists. I'm not sure if it's due to cats itself or the compiler though.


Let's say I want to semigroup combine a couple of tuples of lists

Tuple(List(1, 2)).combine(Tuple(List(5)))

I would get Tuple(List(1, 2, 5)), which is expected.

However if I do

NonEmptyList.of(Tuple(List(1, 2)), Tuple(List(5))).reduce

I would get Tuple(<function>). Looks like my tuples of lists not as tuples of List were inferred as tuples of (Int => Int) which is surprising. I would expect the same Semigroup instance would be used in both examples.

I even got

NonEmptyList.of((List(1, 2), List(1, 2), List(5, 6)), (List(4), List(5), List(7))).reduce

to produce Tuple(List(1, 2, 4),List(1, 2, 5),<function1>) on my local machine using scala-cli on Scala 3.7.4 but I couldn't reproduce elsewhere.

Weirder still, this workaround that looks like it would do nothing

def reduce[T: Semigroup](xs: NonEmptyList[T]) =
  xs.reduce

reduce(Tuple(List(1, 2)).combine(Tuple(List(5))))

produces Tuple(List(1, 2, 5)).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the NonEmptyList.reduce examples with Scala 3.7.4 and compare them with direct tuple combine calls. Inspect the NonEmptyList.reduce entry point and the inferred Semigroup instances for tuple components. Done means the behavior is explained and the reported inconsistency is fixed or documented with regression coverage.

Written by the indexing model from the issue text.

Assessment

Tech stack
scala
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.