-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Stefanos Stefanou
committed
Nov 3, 2023
1 parent
7489375
commit 2b3f034
Showing
13 changed files
with
87 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
package mycats.algebras | ||
import mycats.examples.common.Utils.NonEmptyList | ||
|
||
sealed trait Validated[+E,+A] extends Product with Serializable{} | ||
case class Valid[+A](valid:A) extends Validated[Nothing,A] | ||
case class Invalid[+E](invalid:E) extends Validated[E,Nothing] | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package mycats.algebras | ||
import mycats.examples.common.Utils.NonEmptyList | ||
|
||
object ValidatedNel { | ||
type ValidatedNel[A] = Validated[NonEmptyList[String],A] | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,4 @@ | ||
package mycats.examples.common | ||
|
||
|
||
|
||
|
||
object Utils{ | ||
type NonEmptyList[A] = List[A] //Fake nonEmptyList | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
src/main/scala/mycats/instances/ValidatedNelInstances.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package mycats.instances | ||
import mycats.algebras.Validated | ||
import mycats.examples.common.Utils.NonEmptyList | ||
import mycats.instances.ValidatedInstances.validatedApplicativeErrorInstance | ||
import mycats.lib.morphisms.bi.BiFunctor | ||
import mycats.lib.morphisms.error.ApplicativeError | ||
import mycats.lib.obj.Semigroup | ||
|
||
object ValidatedNelInstances { | ||
implicit def semigroupOfNonEmptyList[A]:Semigroup[NonEmptyList[A]] = (x: NonEmptyList[A], y: NonEmptyList[A]) => x.appendedAll(y) | ||
implicit val validatedNelInstance: ApplicativeError[({type Valid[C] = Validated[NonEmptyList[String], C]})#Valid, NonEmptyList[String]] with BiFunctor[Validated] = validatedApplicativeErrorInstance[NonEmptyList[String]] | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package mycats.lib.syntax | ||
import mycats.lib.obj.Semigroup | ||
|
||
object SemigroupSyntax { | ||
implicit class SemigroupSyntaxOps[A](va:A){ | ||
def combine(vb:A)(implicit semigroupInstance:Semigroup[A]):A = semigroupInstance.combine(va,vb) | ||
} | ||
|
||
} |
Binary file not shown.
Binary file not shown.
23 changes: 11 additions & 12 deletions
23
src/test/scala/mycats/instances/OptionInstancesSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,27 @@ | ||
package mycats.instances | ||
|
||
import mycats.instances.OptionInstances._ | ||
import mycats.lib.syntax.ApplySyntax.applySyntaxOps | ||
import mycats.lib.syntax.InvariantSyntax.InvariantSyntaxOps | ||
import mycats.lib.syntax.SemigroupalSyntax.SemigroupalSyntaxOps | ||
class OptionInstancesSpec extends org.scalatest.funsuite.AnyFunSuite { | ||
val opt1:Option[String]=Some("The meaning of life") | ||
val opt2:Option[Int]=Some(42) | ||
val opt3:Option[String]=Some("42") | ||
|
||
test("Semigroupal Optional: Product should return F[(A,B}]") { | ||
val opt1:Option[String]=Some("The meaning of life") | ||
val opt2:Option[Int]=Some(42) | ||
assert((opt1).product(opt2)==Some(("The meaning of life",42)),"product does not return F[(A,B)] on Option Algebra") | ||
assert((opt1).product(opt2)==Some(("The meaning of life",42)),"Semigroupal's .product does not return F[(A,B)] when applied in Option Algebra") | ||
} | ||
//Functor, ap , imap | ||
test("Invariant Optional: imap should return F[B] given A=>B and B=>A") { | ||
val opt1:Option[String]=Some("The meaning of life") | ||
val opt2:Option[Int]=Some(42) | ||
assert((opt1).product(opt2)==Some(("The meaning of life",42)),"product does not return F[(A,B)] on Option Algebra") | ||
assert(opt3.imap(Integer.valueOf)(String.valueOf)==Some(42),"Invariant Functor's .imap does not transform context when applied in Option Algebra") | ||
} | ||
|
||
test("Functor Optional: map should transform context") { | ||
val opt1:Option[String]=Some("The meaning of life") | ||
val opt2:Option[Int]=Some(42) | ||
assert((opt1).product(opt2)==Some(("The meaning of life",42)),"product does not return F[(A,B)] on Option Algebra") | ||
assert(opt3.map(Integer.valueOf)==Some(42),"Functor's .map does not transform context when applied in Option Algebra") | ||
} | ||
test("Apply Optional: ap should do its ap thing") { | ||
val opt1:Option[String]=Some("The meaning of life") | ||
val opt2:Option[Int]=Some(42) | ||
assert((opt1).product(opt2)==Some(("The meaning of life",42)),"product does not return F[(A,B)] on Option Algebra") | ||
val fnInContext: Option[Int=>String] = Some(String.valueOf) | ||
assert(opt2.ap(fnInContext)==opt3,"product does not return F[(A,B)] on Option Algebra") | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
src/test/scala/mycats/instances/ValidatedInstancesSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package mycats.instances | ||
|
||
import mycats.algebras.ValidatedNel.ValidatedNel | ||
import mycats.algebras.{Invalid, Valid, Validated} | ||
import mycats.examples.common.Expense | ||
import mycats.examples.common.Utils.NonEmptyList | ||
import mycats.instances.ValidatedNelInstances.validatedNelInstance | ||
import mycats.lib.syntax.ApplySyntax.Tuple2ApplyOps | ||
import mycats.instances.ValidatedNelInstances._ | ||
import mycats.lib.syntax.SemigroupSyntax._ | ||
class ValidatedNelInstancesSpec extends org.scalatest.funsuite.AnyFunSuite { | ||
test("Semigroup NonEmptyList: combine should behave as expected") { | ||
val nonEmpty1:NonEmptyList[Int] = 1::2::3::Nil | ||
val nonEmpty2:NonEmptyList[Int] = 4::5::6::Nil | ||
assert(nonEmpty1.combine(nonEmpty2)==(1 to 6).toList,"Semigroupal's .product does not return F[(A,B)] when applied in Option Algebra") | ||
} | ||
//BiFunctor (bimap) | ||
//ApplicativeError (raiseError,handleErrorWith,handleError) | ||
//Applicative (pure) | ||
//Apply (ap) | ||
//Functor (map) | ||
//Arity (map2,product2) | ||
//Invariant(imap) | ||
//Semigroupal(product) | ||
|
||
|
||
|
||
private def expenseIdValidation(expenseID:Long):ValidatedNel[Long]= | ||
if(expenseID<=0) Invalid(List("Expense ID cannot be negative")) else Valid(expenseID) | ||
|
||
private def expenseAmountValidation(expenseAmount:Double):ValidatedNel[Double]= | ||
if(expenseAmount<=0) Invalid(List("Expense amount cannot be negative")) else Valid(expenseAmount) | ||
|
||
private def mkExpenseMapN(id:Long,amount:Double):ValidatedNel[Expense] = | ||
(expenseIdValidation(id), expenseAmountValidation(amount)).mapN((Expense.apply _).tupled) | ||
|
||
} |