Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Created December 21, 2018 13:51
Show Gist options
  • Save yasuabe/ee4105acc47256adb90b307b3e12bbdd to your computer and use it in GitHub Desktop.
Save yasuabe/ee4105acc47256adb90b307b3e12bbdd to your computer and use it in GitHub Desktop.
import cats.data.Chain
import cats.instances.option._
import cats.instances.tuple._
import cats.syntax.bifoldable._
import cats.syntax.bitraverse._
import cats.syntax.option._
import cats.syntax.traverse._
import cats.{Applicative, Bitraverse, Eval}
import scala.language.higherKinds
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) }
}
val tc1: TupleChain[Char, Double] = Chain(('a', 0.1), ('b', 0.2), ('c', 0.3))
val tc2: TupleChain[Char, Double] = Chain(('a', 1.5), ('b', -2.5))
val maybePercent = (d: Double) => if (d < 0) None else s"${d * 100}%".some
tc1.bitraverse(_.toUpper.some, maybePercent)
// res0: Option[TupleChain[Char,String]] = Some(Chain((A,10.0%), (B,20.0%), (C,30.0%)))
tc2.bitraverse(_.toUpper.some, maybePercent)
// res1: Option[TupleChain[Char,String]] = None
tc1.bifoldLeft("")((s, n) => s + s"<$n", (s, n) => s + s",$n>, ")
// res2: String = "<a,0.1>, <b,0.2>, <c,0.3>, "
tc1.bifoldRight(Eval.now(100.0))((a, c) => c.map(_ - (a-'a')), (b, c) => c.map(_ + b)).value
// res3: Double = 97.6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment