Skip to content

Commit

Permalink
Make ByColor more powerful
Browse files Browse the repository at this point in the history
  • Loading branch information
lenguyenthanh committed Jul 9, 2023
1 parent 133c52c commit 6c61034
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 8 deletions.
23 changes: 17 additions & 6 deletions src/main/scala/ByColor.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package chess

import cats.{ Applicative, Eq, Eval, Functor, Monoid, Traverse }
import cats.{ Applicative, Eq, Eval, FlatMap, Functor, Monoid, Semigroupal, Traverse }
import cats.syntax.all.*
import scala.annotation.targetName
import alleycats.Zero

case class ByColor[A](white: A, black: A):
case class ByColor[A](white: A, black: A) extends ByColorSyntax:

inline def apply(inline color: Color) = if color.white then white else black

Expand Down Expand Up @@ -110,10 +110,9 @@ object ByColor:
def combine(x: ByColor[A], y: ByColor[A]) =
ByColor(Monoid[A].combine(x.white, y.white), Monoid[A].combine(x.black, y.black))

given Functor[ByColor] with
def map[A, B](fa: ByColor[A])(f: A => B): ByColor[B] = fa.map(f)
given Functor[ByColor] with Applicative[ByColor] with Traverse[ByColor] with

given Traverse[ByColor] with
override def map[A, B](fa: ByColor[A])(f: A => B): ByColor[B] = fa.map(f)

override def foldLeft[A, B](fa: ByColor[A], b: B)(f: (B, A) => B): B =
fa.fold(b)(f)
Expand All @@ -124,4 +123,16 @@ object ByColor:
def traverse[G[_]: Applicative, A, B](fa: ByColor[A])(f: A => G[B]): G[ByColor[B]] =
fa.traverse(f)

extension [A](p: (A, A)) def asByColor: ByColor[A] = ByColor(p._1, p._2)
def pure[A](a: A): ByColor[A] = ByColor.fill(a)
def ap[A, B](ff: ByColor[A => B])(fa: ByColor[A]): ByColor[B] =
ByColor(ff.white(fa.white), ff.black(fa.black))

trait ByColorSyntax:

extension [F[_], A](bc: ByColor[F[A]])

def mapN[Z](f: (A, A) => Z)(using functor: Functor[F], semigroupal: Semigroupal[F]): F[Z] =
Semigroupal.map2(bc.white, bc.black)(f)

def flatMapN[Z](f: (A, A) => F[Z])(using flatMap: FlatMap[F]): F[Z] =
flatMap.flatMap2(bc.white, bc.black)(f)
4 changes: 2 additions & 2 deletions src/test/scala/ByColorLawsTests.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package chess

import cats.laws.discipline.FunctorTests
import munit.DisciplineSuite
import org.scalacheck.*
import Arbitraries.given
import cats.laws.discipline.TraverseTests
import cats.laws.discipline.{ ApplicativeTests, FunctorTests, TraverseTests }

class ByColorLawsTest extends DisciplineSuite:
checkAll("ByColor.FunctorLaws", FunctorTests[ByColor].functor[Int, Int, String])
checkAll("ByColor.TraverseLaws", TraverseTests[ByColor].traverse[Int, Int, Int, Int, Option, Option])
checkAll("ByColor.ApplicativeLaws", ApplicativeTests[ByColor].applicative[Int, Int, String])
4 changes: 4 additions & 0 deletions src/test/scala/ByColorTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ class ByColorTest extends ScalaCheckSuite:
forAll: (bc: ByColor[Int], f: Int => Boolean) =>
bc.exists(f) == bc.all.exists(f)

test("sequence"):
forAll: (bc: ByColor[Option[Int]]) =>
bc.sequence == (bc.white, bc.black).mapN(ByColor(_, _))

test("findColor && exists"):
forAll: (bc: ByColor[Int], f: Int => Boolean) =>
bc.findColor(f).isDefined == bc.all.exists(f)
Expand Down

0 comments on commit 6c61034

Please sign in to comment.