scalacheck icon indicating copy to clipboard operation
scalacheck copied to clipboard

Introduce `Gen.zipWith` multi-arity method

Open satorg opened this issue 1 year ago • 2 comments

Adds a code generator for Gen.zipWith functions.

Example:

case class Foo(pos: Int, ascii: String, hex: String)

Gen.zipWith(Gen.posNum[Int], Gen.asciiStr, Gen.hexStr)(Foo.apply)

Without Gen.zipWith the same was possible to accomplish with Gen.zip, however it would required an additional map over an intermediary tuple instance:

Gen.zip(Gen.posNum[Int], Gen.asciiStr, Gen.hexStr)
  .map { case (pos, ascii, hex) => Foo(pos, ascii, hex)) }

Therefore Gen.zipWith allows to avoid the intermediate conversion which can come in handy in come cases.

Note that Gen.zipWith starts with arity 2 whereas Gen.zip starts with arity 1. However, I think the latter was an oversight – Gen.zip for arity 1 is a no-op function.

satorg avatar Jul 14 '24 08:07 satorg

Is this intended to behave similarly to mapN, but without the Cats dependency?

rossabaker avatar Aug 12 '24 17:08 rossabaker

Is this intended to behave similarly to mapN, but without the Cats dependency?

Pretty much. To be more accurate, it is supposed to resemble functions map2 through map22 of the Apply typeclass, because mapN requires a tuple to be created first, check this out:

case class Foo(pos: Int, ascii: String, hex: String)

val gen1 = (Gen.posNum[Int], Gen.asciiStr, Gen.hexStr).mapN { Foo.apply }

val gen2 = Apply[Gen].map3(Gen.posNum[Int], Gen.asciiStr, Gen.hexStr) { Foo.apply }

val gen3 = Gen.zipWith(Gen.posNum[Int], Gen.asciiStr, Gen.hexStr) { Foo.apply }

However, there's one catch with the Cats functions: they both use a chain of Functor.product under the hood, which in turn calls to Gen.zip with arity 2. I.e. the Cats functions incur a bunch of intermediary tuples on every evaluation to be created.

satorg avatar Aug 13 '24 02:08 satorg

@rossabaker , thank you for the review!

I'm sorry it got so desperately lonely you had to talk to a bot.

No worries! Actually, I just wanted to check out that "copilot review" feature – to see how it works, what the output looks like, etc. So I thought – what could be better than some my own PR for that?

satorg avatar Jun 15 '25 06:06 satorg