From d43eeaa14afb86d50f0be0274cd6256bac9940fa Mon Sep 17 00:00:00 2001
From: "quentin.leblanc@etu.hesge.ch" <quentin.leblanc@etu.hesge.ch>
Date: Thu, 20 Feb 2020 15:56:17 +0100
Subject: [PATCH] TP4

---
 TP3/build.sbt                         |  3 ++
 TP3/src/main/scala/3.fp.scala         |  8 ++--
 TP3/src/main/scala/4.lambda.scala     | 64 +++++++++++++++++++++++++++
 TP3/src/test/scala/4.lambdaTest.scala | 50 +++++++++++++++++++++
 4 files changed, 122 insertions(+), 3 deletions(-)
 create mode 100644 TP3/src/main/scala/4.lambda.scala
 create mode 100644 TP3/src/test/scala/4.lambdaTest.scala

diff --git a/TP3/build.sbt b/TP3/build.sbt
index 6e42885..dcb4679 100644
--- a/TP3/build.sbt
+++ b/TP3/build.sbt
@@ -3,3 +3,6 @@ name := "TP3"
 version := "0.1"
 
 scalaVersion := "2.13.1"
+
+libraryDependencies += "org.scalactic" %% "scalactic" % "3.1.0"
+libraryDependencies += "org.scalatest" %% "scalatest" % "3.1.0" % "test"
\ No newline at end of file
diff --git a/TP3/src/main/scala/3.fp.scala b/TP3/src/main/scala/3.fp.scala
index 9120c7c..2e89549 100644
--- a/TP3/src/main/scala/3.fp.scala
+++ b/TP3/src/main/scala/3.fp.scala
@@ -74,7 +74,7 @@ object Serie3 {
   @scala.annotation.tailrec
   final def and(xs: List[Boolean] ): Boolean = {
     xs match {
-      case true :: Nil => true
+      case Nil => true
       case true :: bs => and(bs)
       case _ => false
     }
@@ -108,8 +108,10 @@ object Serie3 {
    *  implémentation ne peut utiliser aucune fonction de List !  Vous
    *  devez utiliser le pattern matching.
    */
-  def even[A]( as: List[A] ): Boolean = {
-    len(as)%2 == 0
+  final def even[A]( as: List[A] ): Boolean = as match{
+    case Nil => true
+    case _ :: Nil => false
+    case _ :: _ :: rest => even(rest)
   }
 
 }
diff --git a/TP3/src/main/scala/4.lambda.scala b/TP3/src/main/scala/4.lambda.scala
new file mode 100644
index 0000000..3ad87fa
--- /dev/null
+++ b/TP3/src/main/scala/4.lambda.scala
@@ -0,0 +1,64 @@
+ /*
+ * Implémenter les fonctions suivantes en suivant les commentaires.
+ */
+
+object Predicates {
+
+  type P[A] = A=>Boolean
+
+  /*
+   * La méthode 'not' retourne un nouveau prédicat dont le résultat
+   * est toujours la négation du résultat de l'argument.
+   */
+  def not[A]( p: A =>Boolean ): A =>Boolean = { a:A =>
+    !p(a)
+  }
+
+  /*
+   * La méthode 'and' retourne un nouveau prédicat dont le résultat
+   * est toujours la conjonction des résultats des deux arguments.
+   */
+  def and[A](p1: A =>Boolean, p2: A =>Boolean ): A =>Boolean = { a:A =>
+    p1(a)&&p2(a)
+  }
+
+  /*
+   * La fonction 'or' retourne un nouveau prédicat dont le résultat
+   * est toujours la disjonction des résultats des deux arguments.
+   */
+  def or[A](p1: A =>Boolean, p2: A =>Boolean ): A =>Boolean = { a:A =>
+    p1(a)||p2(a)
+  }
+
+  /*
+   * La fonction 'exists' retourne un nouveau prédicat dont le
+   * résultat est vrai si au moins un des prédicat de l'argument est
+   * vrai.
+   */
+  def exists[A]( ps: List[A =>Boolean] ): A =>Boolean = { a:A =>
+    @scala.annotation.tailrec
+    def existRec(rest: List[P[A]], a: A): Boolean = rest match {
+      case Nil => false
+      case h :: _ if h(a) => true
+      case _ :: t => existRec(t, a)
+    }
+    existRec(ps, a)
+  }
+
+  /*
+   * La fonction 'forall' retourne un nouveau prédicat dont le
+   * résultat est vrai si et seulement si tous les prédicats de
+   * l'argument sont vrais.
+   */
+  def forall[A]( ps: List[A =>Boolean] ): A =>Boolean = { a:A =>
+    @scala.annotation.tailrec
+    def forAllRec(rest: List[P[A]], a:A): Boolean = rest match{
+      case Nil => true
+      case h :: _ if !h(a) => false
+      case _ :: t => forAllRec(t, a)
+    }
+    forAllRec(ps, a)
+  }
+
+
+}
diff --git a/TP3/src/test/scala/4.lambdaTest.scala b/TP3/src/test/scala/4.lambdaTest.scala
new file mode 100644
index 0000000..3575b4c
--- /dev/null
+++ b/TP3/src/test/scala/4.lambdaTest.scala
@@ -0,0 +1,50 @@
+import org.scalatest.funsuite.AnyFunSuite
+
+import Predicates._
+
+class PredicatesSuite4 extends AnyFunSuite {
+
+
+  val big = (_:Int) >= 100
+  val even = (_:Int) % 2 == 0
+
+  val small = not[Int]( big )
+  val bae = and[Int]( big, even )
+  val boe = or[Int]( big, even )
+
+  test("Predicate Evaluation") {
+    assert( big(200) )
+    assert( ! big(19) )
+    assert( even(200) )
+    assert( ! even(201) )
+  }
+
+  test("Predicate negation") {
+    assert( small(19) )
+    assert( !small( 200 ) )
+  }
+
+  test("Predicate AND") {
+    assert( bae( 200 ) )
+    assert( !bae( 201 ) )
+  }
+
+  test("Predicate OR") {
+    assert( boe( 201 ) )
+    assert( !boe( 19 ) )
+  }
+
+  val mul3 = (_:Int ) % 3 == 0
+  val ps = List( big, even, mul3 )
+
+  test("Predicates FORALL") {
+    assert( forall[Int]( ps )( 402 ) )
+    assert( ! forall[Int]( ps )( 200 ) )
+  }
+
+  test("Predicates EXISTS") {
+    assert( exists[Int]( ps )( 18 ) )
+    assert( ! exists[Int]( ps )( 1 ) )
+  }
+
+}
-- 
GitLab