Open satorg opened 4 months ago
Is this intended to behave similarly to mapN, but without the Cats dependency?
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.
Adds a code generator for
Gen.zipWith
functions.Example:
Without
Gen.zipWith
the same was possible to accomplish withGen.zip
, however it would required an additionalmap
over an intermediary tuple instance: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 whereasGen.zip
starts with arity 1. However, I think the latter was an oversight –Gen.zip
for arity 1 is a no-op function.