Skip to content

Instantly share code, notes, and snippets.

@ghostdogpr
Created January 6, 2020 09:50
Show Gist options
  • Save ghostdogpr/2c268f576db1c0274ee6a3d4791b081a to your computer and use it in GitHub Desktop.
Save ghostdogpr/2c268f576db1c0274ee6a3d4791b081a to your computer and use it in GitHub Desktop.
import magnolia.{ CaseClass, Magnolia, SealedTrait }
import mercator.Monadic
import zio.random.Random
import zio.test.{ Gen, Sized }
object Generators {
implicit val genUnit: Typeclass[Unit] = Gen.unit
implicit val genBool: Typeclass[Boolean] = Gen.boolean
implicit val genString: Typeclass[String] = Gen.small(Gen.stringN(_)(Gen.alphaNumericChar))
implicit val genLong: Typeclass[Long] = Gen.anyLong
implicit val genInt: Typeclass[Int] = Gen.anyInt
implicit def genOption[A](implicit ev: Typeclass[A]): Typeclass[Option[A]] = Gen.option(ev)
implicit def genEither[A, B](implicit ev1: Typeclass[A], ev2: Typeclass[B]): Typeclass[Either[A, B]] = Gen.either(ev1, ev2)
implicit def genList[A](implicit ev: Typeclass[A]): Typeclass[List[A]] = Gen.small(Gen.listOfN(_)(ev))
implicit def genSet[A](implicit ev: Typeclass[A]): Typeclass[Set[A]] = genList(ev).map(_.toSet)
implicit def genTuple[A, B](implicit ev1: Typeclass[A], ev2: Typeclass[B]): Typeclass[(A, B)] = ev1.flatMap(a => ev2.map((a, _)))
implicit def genMap[A, B](implicit ev1: Typeclass[A], ev2: Typeclass[B]): Typeclass[Map[A, B]] = genList(genTuple(ev1, ev2)).map(_.toMap)
object Derivation {
type Typeclass[T] = Gen[Random with Sized, T]
implicit val monadic: Monadic[Typeclass] = new Monadic[Typeclass] {
override def point[A](value: A): Typeclass[A] = Gen.const(value)
override def flatMap[A, B](from: Typeclass[A])(fn: A => Typeclass[B]): Typeclass[B] = from.flatMap(fn)
override def map[A, B](from: Typeclass[A])(fn: A => B): Typeclass[B] = from.map(fn)
}
def combine[T](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = caseClass.constructMonadic(_.typeclass)
def dispatch[T](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = Gen.oneOf(sealedTrait.subtypes.map(_.typeclass): _*)
implicit def gen[T]: Typeclass[T] = macro Magnolia.gen[T]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment