Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Created December 21, 2018 14:01
Show Gist options
  • Save yasuabe/26ecc3ebfaf725ca90a05fd820ae0603 to your computer and use it in GitHub Desktop.
Save yasuabe/26ecc3ebfaf725ca90a05fd820ae0603 to your computer and use it in GitHub Desktop.
package adcal_1222
import adcal_1222.TupleChain.TupleChain
import cats.data.Chain
import cats.instances.AllInstances
import cats.instances.tuple._
import cats.laws.discipline.BitraverseTests
import cats.syntax.bifoldable._
import cats.syntax.bitraverse._
import cats.syntax.traverse._
import cats.{Applicative, Apply, Bitraverse, Eval}
import org.scalacheck.{Arbitrary, Gen}
import org.specs2.Specification
import org.typelevel.discipline.specs2.Discipline
import scala.language.higherKinds
object TupleChain {
type TupleChain[A, B] = Chain[(A, B)]
implicit val bitraverserTupleChain = new Bitraverse[TupleChain] {
def bitraverse[G[_], A, B, C, D](
fab: TupleChain[A, B])(f: A => G[C], g: B => G[D])(implicit ev: Applicative[G]): G[TupleChain[C, D]] =
fab.map(_.bitraverse(f, g)).sequence
def bifoldLeft[A, B, C](fab: TupleChain[A, B], c: C)(f: (C, A) => C, g: (C, B) => C): C =
fab.foldLeft(c) { (cc, d) => d.bifoldLeft(cc)(f, g) }
def bifoldRight[A, B, C](fab: TupleChain[A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], g: (B, Eval[C]) => Eval[C]) =
fab.foldRight(c) { _.bifoldRight(_)(f, g) }
}
}
import adcal_1222.TupleChain._
import cats.syntax.apply._
import org.scalacheck.Gen.{chooseNum, listOfN}
class BitraverseSpec extends Specification with Discipline with AllInstances {
implicit val applyInstance: Apply[Gen] = new Apply[Gen] {
def ap[A, B](ff: Gen[A => B])(fa: Gen[A]): Gen[B] = ff flatMap fa.map
def map[A, B](fa: Gen[A])(f: A => B): Gen[B] = fa map f
}
implicit val arbTupleChain: Arbitrary[TupleChain[Int, Int]] = Arbitrary(for {
len <- chooseNum(0, 3)
tuples <- listOfN(len, (chooseNum(0, 3), chooseNum(0, 3)).mapN((_, _)))
} yield Chain.fromSeq(tuples))
private val bitraverseCheck =
checkAll("bt", BitraverseTests[TupleChain].bitraverse[Option, Int, Int, Int, Int, Int, Int ])
def is = s2"""
TupleChain[Int, Int] satisfies bitraverse laws $bitraverseCheck
"""
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment