Skip to content

Commit

Permalink
Merge pull request #85 from Kevin-Lee/task/82/add-option-semigroup-an…
Browse files Browse the repository at this point in the history
…d-option-monoid

Close #82 - Add OptionSemiGroup and OptionMonoid
  • Loading branch information
kevin-lee authored Sep 28, 2019
2 parents ca5f05d + cb28cc1 commit f0dd02b
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 5 deletions.
14 changes: 12 additions & 2 deletions src/main/scala/just/fp/Monoid.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ trait Monoid[A] extends SemiGroup[A] {
def monoidLaw: MonoidLaw = new MonoidLaw {}
}

object Monoid {
object Monoid extends OptionMonoidInstance {

implicit def listMonoid[A]: Monoid[List[A]] = new Monoid[List[A]] with ListSemiGroup[A] {
override def zero: List[A] = Nil
Expand Down Expand Up @@ -75,4 +75,14 @@ object Monoid {
override def zero: BigDecimal = BigDecimal(0)
}

}
}

private[fp] trait OptionMonoidInstance extends OptionSemiGroupInstance {
implicit def optionMonoid[A](implicit F0: SemiGroup[A]): Monoid[Option[A]] =
new Monoid[Option[A]] with OptionSemigroup[A] {

override implicit def F: SemiGroup[A] = F0

override def zero: Option[A] = None
}
}
26 changes: 25 additions & 1 deletion src/main/scala/just/fp/SemiGroup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ trait SemiGroup[A] {
def append(a1: A, a2: => A): A
}

object SemiGroup {
object SemiGroup extends OptionSemiGroupInstance {

trait ListSemiGroup[A] extends SemiGroup[List[A]] {
override def append(a1: List[A], a2: => List[A]): List[A] = a1 ++ a2
Expand Down Expand Up @@ -60,3 +60,27 @@ object SemiGroup {
}
implicit val bigDecimalSemiGroup: SemiGroup[BigDecimal] = new BigDecimalSemiGroup {}
}

private[fp] trait OptionSemigroup[A] extends SemiGroup[Option[A]] {

implicit def F: SemiGroup[A]

override def append(a1: Option[A], a2: => Option[A]): Option[A] = (a1, a2) match {
case (Some(x), Some(y)) =>
Some(implicitly[SemiGroup[A]].append(x, y))
case (Some(x), None) =>
Some(x)
case (None, Some(y)) =>
Some(y)
case (None, None) =>
None
}
}

private[fp] trait OptionSemiGroupInstance {

implicit def optionSemigroup[A](implicit F0: SemiGroup[A]): SemiGroup[Option[A]] =
new OptionSemigroup[A] {
override implicit def F: SemiGroup[A] = F0
}
}
12 changes: 11 additions & 1 deletion src/test/scala/just/fp/MonoidSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import hedgehog.runner._
object MonoidSpec extends Properties {

override def tests: List[Test] = List(
property("testListMonoidLaw", ListMonoidLaws.laws)
property("testOptionMonoidLaw", OptionMonoidLaws.laws)
, property("testListMonoidLaw", ListMonoidLaws.laws)
, property("testVectorMonoidLaw", VectorMonoidLaws.laws)
, property("testStringMonoidLaw", StringMonoidLaws.laws)
, property("testByteMonoidLaw", ByteMonoidLaws.laws)
Expand Down Expand Up @@ -40,6 +41,15 @@ object MonoidSpec extends Properties {
)
}

object OptionMonoidLaws {
def genOption: Gen[Option[Int]] = Gens.genOption(Gens.genIntFromMinToMax)

def laws: Property =
Specs.monoidLaws.laws[Option[Int]](
genOption
)
}

object StringMonoidLaws {
def genString: Gen[String] = Gens.genUnicodeString

Expand Down
4 changes: 3 additions & 1 deletion src/test/scala/just/fp/syntax/SemiGroupSyntaxSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ object SemiGroupSyntaxSpec extends Properties {
import just.fp._

override def tests: List[Test] = List(
property("test List |+| List", testPlus(Gens.genList(Gens.genIntFromMinToMax, 10)))
property("test Option |+| Option", testPlus(Gens.genOption(Gens.genIntFromMinToMax)))
, property("test List |+| List", testPlus(Gens.genList(Gens.genIntFromMinToMax, 10)))
, property("test Vector |+| Vector", testPlus(Gens.genVector(Gens.genIntFromMinToMax, 10)))
, property("test String |+| String", testPlus(Gens.genUnicodeString))
, property("test Byte |+| Byte", testPlus(Gens.genByteFromMinToMax))
Expand All @@ -22,6 +23,7 @@ object SemiGroupSyntaxSpec extends Properties {
, property("test Long |+| Long", testPlus(Gens.genLongFromMinToMax))
, property("test BigInt |+| BigInt", testPlus(Gens.genBigInt))
, property("test BigDecimal |+| BigDecimal", testPlus(Gens.genBigDecimal))
, property("test Option.mappend(Option)", testMappend(Gens.genOption(Gens.genIntFromMinToMax)))
, property("test List.mappend(List)", testMappend(Gens.genList(Gens.genIntFromMinToMax, 10)))
, property("test Vector.mappend(Vector)", testMappend(Gens.genVector(Gens.genIntFromMinToMax, 10)))
, property("test String.mappend(String)", testMappend(Gens.genUnicodeString))
Expand Down

0 comments on commit f0dd02b

Please sign in to comment.