From 3ae230e928965c87e89a1fdb407353c2c32e81ec Mon Sep 17 00:00:00 2001
From: Quentin <quentin.leblanc@etu.hesge.ch>
Date: Tue, 14 Apr 2020 12:15:39 +0200
Subject: [PATCH] tp final

---
 TP3/project/build.properties          |  0
 TP3/src/main/scala/8.monoids.scala    | 24 ++++++--
 TP3/src/main/scala/9.Entities.scala   | 79 +++++++++++++++++++++++++++
 TP3/src/test/scala/8.monoidTest.scala |  5 ++
 4 files changed, 104 insertions(+), 4 deletions(-)
 mode change 100644 => 100755 TP3/project/build.properties
 create mode 100644 TP3/src/main/scala/9.Entities.scala

diff --git a/TP3/project/build.properties b/TP3/project/build.properties
old mode 100644
new mode 100755
diff --git a/TP3/src/main/scala/8.monoids.scala b/TP3/src/main/scala/8.monoids.scala
index e2a4744..9a813f0 100755
--- a/TP3/src/main/scala/8.monoids.scala
+++ b/TP3/src/main/scala/8.monoids.scala
@@ -111,18 +111,34 @@ object Examples {
   def minMax( as: List[Double] ): (Double,Double) = mapReduce[Double, (Double, Double)](as)((a:Double) => (a, a), tuple2M(doubleMin, doubleMax))
 
   //Série 3: Even
-  def even[A]( as: List[A] ): Boolean = mapReduce[A, Int](as)(_ => 1, intSum)%2 == 0
+  def even[A]( as: List[A] ): Boolean = mapReduce(as)(a=>false, Monoid(true)(_ == _))
 
   //Compte le nombre d'occurence de chaque objet de la liste
-  def count[A]( as: List[A] ): Map[A,Int] = mapReduce[A, Map[A, Int]](as)((x: A) => Map[A, Int](x -> 1), mapM[A, Int](Monoid[Int](0)(_ + _)))
+  def count[A]( as: List[A] ): Map[A,Int] = mapReduce[A, Map[A, Int]](as)((x: A) => Map[A, Int](x -> 1), mapM[A, Int](intSum))
 
   //Compte le nombre d'occurence de chaque pair d'objet
-  def count2[A,B]( as: List[(A,B)] ): Map[A,Map[B,Int]] = mapReduce[(A,B), Map[A,Map[B, Int]]](as)( (x:(A,B)) => Map(x._1 -> Map(x._2 -> 1)),mapM[A,Map[B, Int]](mapM[B, Int](Monoid[Int](0)(_ + _))))
+  def count2[A,B]( as: List[(A,B)] ): Map[A,Map[B,Int]] = mapReduce[(A,B), Map[A,Map[B, Int]]](as)( (x:(A,B)) => Map(x._1 -> Map(x._2 -> 1)),mapM[A,Map[B, Int]](mapM[B, Int](intSum)))
 
   //Série 4: forall
-  def forall[A]( ps: List[(A)=>Boolean] ): (A)=>Boolean = (a:A) => { mapReduce(ps)((p:A=>Boolean) => p(a), Monoid[Boolean](true)(_ && _)) }
+  def funcM[A,B](MB: Monoid[B]) = {
+    Monoid[A=>B](a => MB.zero){ (f:A=>B, g:A=>B) => (a:A) => MB.op(f(a), g(a))}
+  }
+
+  def forall[A]( ps: List[(A)=>Boolean] ): (A)=>Boolean = reduce(ps)(funcM(Monoid[Boolean](true)(_ && _)))
+
 
+  def sortedList[A](as1:List[A], as2:List[A], smallerThan: (A,A)=>Boolean) = {
+    def mergeR(l1: List[A], l2: List[A], res:List[A]): List[A] = (l1,l2) match {
+      case (Nil, _) => res.reverse ++ l2
+      case (_, Nil) => res.reverse ++ l1
+      case (h1::t1, h2::t2) =>
+        if(smallerThan(h1,h2)) mergeR(t1, l2, h1::res)
+        else mergeR(l1,t2, h2::res)
+    }
+    mergeR(as1, as2, Nil)
+  }
 
+  //def sort( as: List[Double]): List[Double] =
 }
 
 
diff --git a/TP3/src/main/scala/9.Entities.scala b/TP3/src/main/scala/9.Entities.scala
new file mode 100644
index 0000000..2c3d0a5
--- /dev/null
+++ b/TP3/src/main/scala/9.Entities.scala
@@ -0,0 +1,79 @@
+import Monoid.Laws
+
+trait Monoid[A] {
+  def op( a1: A, a2: A ): A
+  def zero: A
+}
+
+object Monoid {
+  def apply[A]( z: A )( f: (A,A)=>A ) = new Monoid[A] {
+    def op( a1: A, a2: A ): A = f(a1,a2)
+    def zero: A = z
+  }
+
+  object Laws {
+    def checkAssociativity[A](mon: Monoid[A], a1: A, a2: A, a3: A) = {
+      import mon.op
+      op(a1,op(a2,a3)) == op(op(a1,a2),a3)
+    }
+    def checkNeutral[A](mon: Monoid[A], a: A) = {
+      import mon._
+      op(zero,a) == a && op(a,zero) == a
+    }
+  }
+}
+
+case class Module[+A](name: String, args: Map[String, A]){
+  override def toString: String = {
+    s"Name : $name. Args : ${args.toString()}"
+  }
+}
+
+case class Task(modules: List[Module[Any]]){
+  override def toString: String = {
+    s"Modules : ${modules.toString()}\n"
+  }
+}
+
+object TaskMonoid{
+  def + = Monoid[Task](Task(Nil))( (t1, t2) =>
+    Task(t1.modules:::t2.modules))
+
+  def mapReduce[A,B]( as: List[A] )(f: A=>B, M: Monoid[B]): B = {
+    def rec( rem: List[A], acc: B ): B = rem match {
+      case Nil => acc
+      case h :: t => rec( t, M.op(acc, f(h) ) )
+    }
+    rec( as, M.zero )
+  }
+  def reduce[A]( as: List[A] )( M: Monoid[A] ): A =
+    mapReduce( as )( identity, M )
+}
+
+object tp {
+  def main(args: Array[String]): Unit = {
+    import TaskMonoid._
+
+    val m1 = Module("Swiss-Impex", Map("year" -> 2019, "month" -> 1, "category" -> "2709.0090"))
+    val m2 = Module("Fao Genève PROD 2019/11/06", Map("passCaptcha" -> true, "page" -> 1))
+    val m3 = Module("Tâche 3", Map("Oui" -> true, "non" -> false))
+
+    val t1 = Task((m1::Nil))
+    val t2 = Task((m2::Nil))
+    val t3 = Task((m3::Nil))
+
+    val t1p2 = reduce(List(t1, t2))(+)
+    val t1t2t3 = List(t1, t2, t3)
+    val t1t2 = List(t1, t2)
+    val t1t3 = List(t1, t3)
+    val t2t3 = List(t2,t3)
+
+
+    println("========== TEST ASSOCIATIVITE ===========\n")
+    println((reduce(List(t1, reduce(t2t3)(+)))(+) == reduce(List(reduce(t1t2)(+), t3))(+)))
+    println()
+    println("========== TEST ELEMENT NEUTRE ==========\n")
+    println(t1 == reduce(List(t1,Task(Nil)))(+) && t1 == reduce(List(Task(Nil), t1))(+))
+
+  }
+}
\ No newline at end of file
diff --git a/TP3/src/test/scala/8.monoidTest.scala b/TP3/src/test/scala/8.monoidTest.scala
index 736232e..00004d8 100755
--- a/TP3/src/test/scala/8.monoidTest.scala
+++ b/TP3/src/test/scala/8.monoidTest.scala
@@ -58,6 +58,11 @@ class Monoid8Suite extends AnyFunSuite {
     assert( forall( Nil )( 200 ) )
   }
 
+  /*test("sort") {
+    val test1 = List(2.0,1.0,5.0,6.0,4.0,8.0,7.0,1.0)
+    assert(sort(test1) == List(1.0,1.0,2.0,4.0,5.0,6.0,7.0,8.0))
+  }*/
+
 
 
 }
-- 
GitLab