Skip to content
Snippets Groups Projects
Commit 81aa9d8c authored by Quentin Leblanc's avatar Quentin Leblanc
Browse files

TP 5

parent d43eeaa1
No related branches found
No related tags found
No related merge requests found
package ch.hepia.scala
/* /*
* Implémenter les fonctions suivantes en suivant les commentaires. * Implémenter les fonctions suivantes en suivant les commentaires.
* Respectez également les consignes suivantes: * Respectez également les consignes suivantes:
......
/* package ch.hepia.scala
/*
* Implémenter les fonctions suivantes en suivant les commentaires. * Implémenter les fonctions suivantes en suivant les commentaires.
*/ */
......
package ch.hepia.scala
/* Implémentez les fonctions suivantes. Vous ne pouvez utiliser que les
* méthode de 'List' vues dans les exercices précédents.
*/
object HKFunc {
/* La fonction 'map' applique une fonction 'f' sur chaque élément de
* la liste 'as'. La liste résultat doit avoir la même longueur que
* l'argument.
*/
def map[A,B]( as: List[A] )( f: A=>B ): List[B] = {
@scala.annotation.tailrec
def applyOnHead(rec: List[A], acc: List[B]): List[B] = rec match {
case Nil => acc
case a :: tail => applyOnHead(tail, f(a)::acc)
}
Serie3.rev(applyOnHead(as, List.empty))
}
/* La fonction 'filter' utilise le prédicat 'f' pour déterminer quel
* élément garder. Le résultat peut être vide, mais l'ordre doit
* être préservé.
bbb */
def filter[A]( as: List[A] )( f: A=>Boolean ): List[A] = {
@scala.annotation.tailrec
def applyOnHead(rec: List[A], acc: List[A]): List[A] = rec match {
case Nil => acc
case a :: tail if f(a) => applyOnHead(tail, a::acc)
case a :: tail if !f(a) => applyOnHead(tail, acc)
}
Serie3.rev(applyOnHead(as, List.empty))
}
/* Réduit une liste 'as' en utilisant une opération binaire 'f'. On
* supposera que 'as' n'est pas vide.
*/
def reduce[A]( as: List[A] )( f: (A,A)=>A ): A = {
@scala.annotation.tailrec
def reduce2Head(rec: List[A], acc: A): A = rec match{
case Nil => acc
case b :: tail => reduce2Head(tail, f(b, acc))
}
reduce2Head(as.tail, as.head)
}
/* Transforme une fonction 'f' en une fonction s'appliquant sur une
* liste. Utiliser la fonction 'map' définie ci-dessus
*/
def lift[A,B]( f: A=>B ): List[A]=>List[B] = { (lstA: List[A]) => map(lstA)(f) }
/* DIFFICILE. Transforme une liste 'as' au moyen de la fonction 'f'.
* Cette fonction est appliquée à chaque élément de 'as' pour
* produire une nouvelle liste (qui peut être vide). Le résultat est
* la concaténation de chaque nouvelle liste en respectant l'ordre.
*/
def bind[A,B]( as: List[A] )( f: A=>List[B] ): List[B] = {
Serie3.flat(map(as)(f))
}
}
package ch.hepia.scala
import org.scalatest.funsuite.AnyFunSuite import org.scalatest.funsuite.AnyFunSuite
import Predicates._ import Predicates._
......
package ch.hepia.scala
import org.scalatest.funsuite.AnyFunSuite
import HKFunc._
class HKFunc5Suite extends AnyFunSuite {
val i0 = List[Int]()
val is = List( 1, 2, 3, 4 )
test("map") {
assert( map( i0 )(_ + 1 ) == i0 )
assert( map( is )(_ + 1 ) == List( 2, 3, 4, 5 ) )
assert( map( is )(_ * 2 ) == List( 2, 4, 6, 8 ) )
}
test("filter") {
assert( filter( i0 )(_ % 2 == 0 ) == i0 )
assert( filter( is )(_ % 2 == 0 ) == List( 2, 4 ) )
}
test("reduce") {
assert( reduce( is )( _ + _ ) == is.sum )
assert( reduce( is )( _ * _ ) == 24 )
}
test("lift") {
val f = (_:Int) + 1
val g = (_:Int) * 2
val id = lift[Int,Int]( identity )
assert( id(i0) == i0 )
assert( id(is) == is )
val h1 = lift( f andThen g )
val h2 = lift(f) andThen lift(g)
assert( h1(i0) == h2(i0) )
assert( h1(is) == h2(is) )
}
test("bind") {
val k = (i:Int) => if( i%2 == 0 ) List( -i, i ) else Nil
val l = (i:Int) => List( i, i )
assert( bind( i0 )( k ) == i0 )
assert( bind( is )( k ) == List( -2, 2, -4, 4 ) )
assert( bind( is )( l ) == List( 1, 1, 2, 2, 3, 3, 4, 4 ) )
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment