Samuel Tardieu @ rfc1149.net

Scala : TD 1

`Paradigmes et langages non classiques 2014

Ce TD permet de manipuler et d’approfondir les différents concepts abordés lors du premier et deuxième cours Scala.

Récupérer le fichier contenant le squelette de l’application.

Le code devra être placé dans un ou plusieurs fichiers localisés dans src/main/scala/. Vous pouvez voir les tests dans src/tests/scala/Tests.scala. Ces tests sont écrits dans un DSL fourni par le paquetage scalatest. Un certain nombre de tests sont écrits, il vous faudra les décommenter au fur et à mesure. Tout le code devra se situer dans le paquetage fr.enst.plnc2014.td1 (voir la directive au début du fichier src/main/scala/td1.scala).

isOdd/isEven

Implémenter des fonctions isOdd et isEven prenant en paramètre un Int et retournant un Boolean (dont on devine aisément ce qu’elles font) et les tester avec la commande test de sbt. Ces fonctions devront être placées dans l’objet TD1 (rappelons qu’il n’existe pas de méthodes statiques en Scala).

Classe paramétrée ExtSeq

Faire une classe ExtSeq paramétrée par un type T prenant comme argument de constructeur un Seq[T] (une séquence abstraite d’objets de type T). Cette classe devra implémenter les méthodes any et all prenant chacune une fonction transformant un objet de type T en Boolean. Un tel type se décrit comme T => Boolean en Scala. Les méthodes doivent respectivement vérifier si au moins un élément respecte la condition passée en argument, et si tous les éléments respectent cette condition.

Un objet compagnon (de même nom que la classe) devra fournir une fonction toExtSeq déclarée comme implicite permettant de transformer un Seq[T] en ExtSeq[T]. Alternativement, on utilisera le fait que, depuis Scala 2.10, une classe déclarée comme implicite voit son constructeur principal automatiquement déclaré comme implicite également.

Décommenter les tests et tester. Si la fonction implicite toExtSeq est bien visible directement, on pourra appliquer les fonctions all et any à tous les types de séquences, par exemple les listes (fonctionalité Pimp my library).

myWhile/doWhile

Implémenter dans l’objet TD1 une fonction myWhile prenant en paramètre un booléen « par nom » (c’est-à-dire non évalué) dont la signature en Scala se note => Boolean ainsi qu’une fonction sans paramètre et retournant n’importe quoi (le résultat sera ignoré) à appeler tant que la condition est vraie. Tester.

Implémenter une classe ExtCond (et son objet associé pour une conversion implicite d’un => Boolean en ce type) qui fournit une méthode doWhile qui fera la même chose que précédemment (mais ne prendra bien sûr que l’action en paramètre). Tester.

Complex

Implémenter un type Complex prenant en paramètre deux doubles (les parties réelle et imaginaire). On utilisera une case class pour bénéficier de certains automatismes comme la définition correcte de l’égalité ou la déconstruction pour l’utilisation dans le cadre du pattern matching. L’affichage, par la surcharge de la méthode toString, devra être naturel, par exemple 1.2 ou -3.4+5.6i ou encore -3.0i. Tester l’affichage.

Implémenter la fonction reciprocal renvoyant le conjugué, ainsi que l’addition entre complexes. Tester.

Autoriser à l’aide d’une fonction implicite les opérations avec les Double. Tester.

Rajouter les autres opérations (-, /, *, abs, etc.) ainsi que des primitives de tests unitaires.

Les N reines

Implémenter dans l’objet TD1 une fonction avec la signature suivante :

def solveQueens(numberOfQueens: Int, f: List[(Int, Int)] => Unit): Unit

qui appelle la fonction f avec chaque liste de paires représentant une solution au problème des numberOfQueens reines. On pourra utiliser si nécessaire les constructions suivantes :