├── OCaml_MOOC_W0_ALL ├── Exercise │ └── W0_S4.ml ├── OCaml_MOOC_W0_S0.pdf ├── OCaml_MOOC_W0_S1.pdf ├── OCaml_MOOC_W0_S2.pdf ├── OCaml_MOOC_W0_S3.pdf ├── OCaml_MOOC_W0_S4.pdf ├── OCaml_MOOC_W0_S5.pdf ├── OCaml_MOOC_W0_S6.pdf ├── W0Hello.srt ├── W0Hello_fr.srt ├── W0Hello_pt.srt ├── W0_S0.srt ├── W0_S0_fr.srt ├── W0_S0_pt.srt ├── W0_S1.srt ├── W0_S1_fr.srt ├── W0_S1_pt.srt ├── W0_S2.srt ├── W0_S2_fr.srt ├── W0_S2_pt.srt ├── W0_S3.srt ├── W0_S3_fr.srt ├── W0_S3_pt.srt ├── W0_S4.srt ├── W0_S4_fr.srt ├── W0_S4_pt.srt ├── W0_S5.srt ├── W0_S5_fr.srt ├── W0_S5_pt.srt ├── W0_S6.srt ├── W0_S6_fr.srt └── W0_S6_pt.srt ├── OCaml_MOOC_W1_ALL ├── Exercise │ ├── W1_S3_1.ml │ ├── W1_S3_2.ml │ ├── W1_S4_1.ml │ ├── W1_S4_2.ml │ └── W1_S5_1.ml ├── OCaml_MOOC_W1_S0.pdf ├── OCaml_MOOC_W1_S1.pdf ├── OCaml_MOOC_W1_S2.pdf ├── OCaml_MOOC_W1_S3.pdf ├── OCaml_MOOC_W1_S4.pdf ├── OCaml_MOOC_W1_S5.pdf ├── W1_S0.srt ├── W1_S0_fr.srt ├── W1_S0_pt.srt ├── W1_S1.srt ├── W1_S1_fr.srt ├── W1_S1_pt.srt ├── W1_S2.srt ├── W1_S2_fr.srt ├── W1_S2_pt.srt ├── W1_S3.srt ├── W1_S3_fr.srt ├── W1_S3_pt.srt ├── W1_S4.srt ├── W1_S4_fr.srt ├── W1_S4_pt.srt ├── W1_S5.srt ├── W1_S5_fr.srt ├── W1_S5_pt.srt ├── application.ml ├── booleans.ml ├── char.ml ├── errors.ml ├── float.ml ├── functions.ml ├── global.ml ├── if.ml ├── integers.ml ├── lexicalscoping.ml ├── local.ml ├── mutual.ml ├── polymorph.ml ├── rec.ml ├── redefinition.ml ├── simultaneous.ml └── string.ml ├── OCaml_MOOC_W2_ALL ├── Exercise │ ├── W2_S1_1.ml │ ├── W2_S2_1.ml │ ├── W2_S2_2.ml │ ├── W2_S3_1.ml │ ├── W2_S3_2.ml │ └── W2_S4.ml ├── OCaml_MOOC_W2_S0.pdf ├── OCaml_MOOC_W2_S1.pdf ├── OCaml_MOOC_W2_S2.pdf ├── OCaml_MOOC_W2_S3.pdf ├── OCaml_MOOC_W2_S4.pdf ├── W1Hello.srt ├── W1Hello_fr.srt ├── W1Hello_pt.srt ├── W2_S0.srt ├── W2_S0_fr.srt ├── W2_S1.srt ├── W2_S1_fr.srt ├── W2_S2.srt ├── W2_S2_fr.srt ├── W2_S3.srt ├── W2_S3_fr.srt ├── W2_S4.srt ├── W2_S4_fr.srt ├── ambiguousField.ml ├── colors.ml ├── db.ml ├── equality.ml ├── extractCoordinates.ml ├── heterogeneous.ml ├── illtypedField.ml ├── invalidExtract.ml ├── invalidPattern.ml ├── literal.ml ├── missingField.ml ├── multipleTypeDefinition.ml ├── outofbound.ml ├── predicate.ml ├── seq.ml ├── set.ml ├── smallCoordinates.ml ├── smallCoordinates2.ml ├── smallCoordinatesWithTypeAnnotations.ml ├── stdSwap.ml ├── swap.ml ├── typeAnnotations.ml └── typofield.ml ├── OCaml_MOOC_W3_ALL ├── Exercise │ ├── W3_S0_1.ml │ ├── W3_S0_2.ml │ ├── W3_S0_3.ml │ ├── W3_S1_1.ml │ ├── W3_S1_2.ml │ ├── W3_S2_1.ml │ ├── W3_S2_2.ml │ ├── W3_S3.ml │ ├── W3_S4_1.ml │ ├── W3_S4_2.ml │ └── W3_S5.ml ├── OCaml_MOOC_W3_S0.pdf ├── OCaml_MOOC_W3_S1.pdf ├── OCaml_MOOC_W3_S2.pdf ├── OCaml_MOOC_W3_S3.pdf ├── OCaml_MOOC_W3_S4.pdf ├── OCaml_MOOC_W3_S5.pdf ├── W3_S0.srt ├── W3_S0_fr.srt ├── W3_S1.srt ├── W3_S1_fr.srt ├── W3_S2.srt ├── W3_S2_fr.srt ├── W3_S3.srt ├── W3_S3_fr.srt ├── W3_S4.srt ├── W3_S4_fr.srt ├── W3_S5.srt ├── W3_S5_fr.srt ├── aspat.ml ├── bst.ml ├── color.ml ├── disjunctive.ml ├── either.ml ├── incompatiblePatterns.ml ├── intList.ml ├── intListLen.ml ├── invalidArity.ml ├── light.ml ├── listFastRev.ml ├── listLen.ml ├── listRev.ml ├── listUnique.ml ├── money.ml ├── option.ml ├── query.ml ├── storyTeller.ml ├── unboundTypeVariable.ml └── when.ml ├── OCaml_MOOC_W4_ALL ├── Exercise │ ├── W4_S0.ml │ ├── W4_S1.ml │ ├── W4_S2.ml │ ├── W4_S3_1.ml │ ├── W4_S3_2.ml │ ├── W4_S4.ml │ ├── W4_S5_1.ml │ └── W4_S5_2.ml ├── OCaml_MOOC_W4_S0.pdf ├── OCaml_MOOC_W4_S1.pdf ├── OCaml_MOOC_W4_S2.pdf ├── OCaml_MOOC_W4_S3.pdf ├── OCaml_MOOC_W4_S4.pdf ├── OCaml_MOOC_W4_S5.pdf ├── W4_S0.srt ├── W4_S0_fr.srt ├── W4_S1.srt ├── W4_S1_fr.srt ├── W4_S2.srt ├── W4_S2_fr.srt ├── W4_S3.srt ├── W4_S3_fr.srt ├── W4_S4.srt ├── W4_S4_fr.srt ├── W4_S5.srt ├── W4_S5_fr.srt ├── arg.ml ├── associative.ml ├── counting.ml ├── eval.ml ├── foldleft.ml ├── foldright.ml ├── innerproduct.ml ├── lambda1.ml ├── lambda2.ml ├── list.ml ├── listegal.ml ├── map.ml ├── map2.ml ├── matrixsum.ml ├── partial.ml ├── pattern.ml ├── powerset.ml ├── reduction.ml ├── result.ml ├── return.ml └── vectorsum.ml ├── OCaml_MOOC_W5_ALL ├── Exercise │ ├── W5_S1.ml │ ├── W5_S2_1.ml │ ├── W5_S2_2.ml │ ├── W5_S3_1.ml │ ├── W5_S3_2.ml │ ├── W5_S4_1.ml │ ├── W5_S4_2.ml │ ├── W5_S5.ml │ ├── W5_S6_1.ml │ └── W5_S6_2.ml ├── OCaml_MOOC_W5_S0.pdf ├── OCaml_MOOC_W5_S1.pdf ├── OCaml_MOOC_W5_S2.pdf ├── OCaml_MOOC_W5_S3.pdf ├── OCaml_MOOC_W5_S4.pdf ├── OCaml_MOOC_W5_S5.pdf ├── OCaml_MOOC_W5_S6.pdf ├── W5_S0.srt ├── W5_S0_fr.srt ├── W5_S1.srt ├── W5_S2.srt ├── W5_S3.srt ├── W5_S3_fr.srt ├── W5_S4.srt ├── W5_S4_fr.srt ├── W5_S5.srt ├── W5_S5_fr.srt ├── W5_S6.srt ├── arraymutables.ml ├── errorexc.ml ├── headexc.ml ├── log2int.ml ├── mutablerecord.ml ├── read_intlist.ml ├── recordreview.ml ├── refs.ml ├── squarecubes.ml └── trywith.ml ├── OCaml_MOOC_W6_ALL ├── Exercise │ ├── W6_S0_1.ml │ ├── W6_S0_2.ml │ ├── W6_S0_3.ml │ ├── W6_S1_1.ml │ ├── W6_S1_2.ml │ ├── W6_S2.ml │ └── W6_S3.ml ├── OCaml_MOOC_W6_S0.pdf ├── OCaml_MOOC_W6_S1.pdf ├── OCaml_MOOC_W6_S2.pdf ├── OCaml_MOOC_W6_S3.pdf ├── OCaml_MOOC_W6_S4.pdf ├── W6_S0.srt ├── W6_S1.srt ├── W6_S2.srt ├── W6_S3.srt ├── W6_S4.srt ├── badSignature.ml ├── dict.ml ├── dict2.ml ├── dictfunctor.ml ├── goodSignature.ml ├── hideValues.ml ├── stack.ml ├── stackImplementation.ml └── tree.ml ├── Projects └── klotski.ml ├── README.md ├── ocaml-4.07-refman.pdf └── ocaml-ora-book.pdf /OCaml_MOOC_W0_ALL/Exercise/W0_S4.ml: -------------------------------------------------------------------------------- 1 | (* 2 | GRADING ENVIRONMENT (TEST-BED) (40/40 points) 3 | In this test-bed exercise you are asked to (re)implement the basic integer-arithmetic functions. 4 | 5 | Write a function plus of type int -> int -> int. 6 | Write a function minus of type int -> int -> int. 7 | Write a function times of type int -> int -> int. 8 | Write a function divide of type int -> int -> int. 9 | The preloaded template contains a minor syntax error and is only a partially valid answer. These errors were introduced in order to let you experiment with the error reporting mechanism and the grading report. 10 | Feel free to introduce more errors and to stress the system, the resulting grade for this exercise will not be taken into account in the global grade and you might submit as many solutions as you wish. 11 | If you end up writing an infinite computation, the system will detect it after a while and ask you to stop the script. It will slow your browser down until that point, since everything is done on your side, via your JavaScript engine. So don't worry, you can try and break the system as much as you want, it should not break anything on our servers. 12 | 13 | THE GIVEN PRELUDE 14 | 15 | (* Some code is loaded in the toplevel before your code. *) 16 | 17 | let greetings = "Hello world!" 18 | *) 19 | 20 | let plus x y = x + y ;; 21 | 22 | let minus x y = x - y ;; 23 | 24 | let times x y = x * y ;; 25 | 26 | let divide x y = x / y ;; -------------------------------------------------------------------------------- /OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S0.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S1.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S2.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S3.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S4.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S5.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W0_ALL/OCaml_MOOC_W0_S6.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W0_ALL/W0Hello.srt: -------------------------------------------------------------------------------- 1 | 1 2 | 00:00:02,240 --> 00:00:03,500 3 | Hello. 4 | 5 | 2 6 | 00:00:03,500 --> 00:00:07,010 7 | Welcome to this online course 8 | on functional programming in OCaml. 9 | 10 | 3 11 | 00:00:07,010 --> 00:00:09,580 12 | My name is Xavier Leroy. 13 | 14 | 4 15 | 00:00:09,580 --> 00:00:12,580 16 | I'm a research scientist, here in France. 17 | 18 | 5 19 | 00:00:12,580 --> 00:00:18,050 20 | And one of the designers and implementers 21 | of the OCaml language, 22 | 23 | 6 24 | 00:00:18,050 --> 00:00:20,720 25 | that you are going to use in this course. 26 | 27 | 7 28 | 00:00:20,720 --> 00:00:23,170 29 | So this is the first MOOC on OCaml, 30 | 31 | 8 32 | 00:00:23,170 --> 00:00:30,539 33 | that means a lot to me and to the other 34 | developers of the OCaml system. 35 | 36 | 9 37 | 00:00:30,539 --> 00:00:34,680 38 | So we are thrilled to see so many of you 39 | joining this course. 40 | 41 | 10 42 | 00:00:34,680 --> 00:00:37,970 43 | And we are also very grateful 44 | to the three instructors, 45 | 46 | 11 47 | 00:00:37,970 --> 00:00:42,820 48 | and every one who participated 49 | in setting up this course. 50 | 51 | 12 52 | 00:00:42,820 --> 00:00:46,710 53 | If you already have some notion of 54 | functional programming, 55 | 56 | 13 57 | 00:00:46,710 --> 00:00:50,130 58 | I hope you will find OCaml to be robust, and 59 | 60 | 14 61 | 00:00:50,130 --> 00:00:54,870 62 | a very effective programming language for 63 | that style of programming. 64 | 65 | 15 66 | 00:00:54,870 --> 00:00:57,400 67 | It has plenty of application areas, 68 | 69 | 16 70 | 00:00:57,400 --> 00:00:59,780 71 | like software verification tools, 72 | 73 | 17 74 | 00:00:59,780 --> 00:01:02,860 75 | static analysis, theorem proving, 76 | 77 | 18 78 | 00:01:02,860 --> 00:01:05,460 79 | but also in web programming, 80 | 81 | 19 82 | 00:01:05,460 --> 00:01:06,500 83 | in system programming, 84 | 85 | 20 86 | 00:01:06,500 --> 00:01:09,359 87 | in the financial industry, 88 | 89 | 21 90 | 00:01:09,359 --> 00:01:11,859 91 | or bio-informatics, 92 | 93 | 22 94 | 00:01:11,859 --> 00:01:14,159 95 | and many other exciting application areas, 96 | 97 | 23 98 | 00:01:14,159 --> 00:01:18,560 99 | where OCaml is a really good match. 100 | 101 | 24 102 | 00:01:18,560 --> 00:01:22,280 103 | But if this is your first exposure to 104 | functional programming, 105 | 106 | 25 107 | 00:01:22,280 --> 00:01:24,329 108 | frankly, I envy you. 109 | 110 | 26 111 | 00:01:24,329 --> 00:01:28,399 112 | Because it reminds me of my first exposure 113 | to functional programming, 114 | 115 | 27 116 | 00:01:28,399 --> 00:01:31,299 117 | that was a long time ago. 118 | 119 | 28 120 | 00:01:31,299 --> 00:01:34,530 121 | And at the beginning it felt weird... 122 | 123 | 29 124 | 00:01:34,530 --> 00:01:39,590 125 | everything was slightly different from what 126 | I knew about programming at that time. 127 | 128 | 30 129 | 00:01:39,590 --> 00:01:43,900 130 | But after a while, it all clinked into place, 131 | and I was struck, 132 | 133 | 31 134 | 00:01:43,900 --> 00:01:50,310 135 | and even seduced by the elegance and expressiveness 136 | of this programming style. 137 | 138 | 32 139 | 00:01:50,310 --> 00:01:55,509 140 | And so much so that then 141 | I spent many years working on OCaml. 142 | 143 | 33 144 | 00:01:55,509 --> 00:02:01,889 145 | Just to make functional programming 146 | more usable in practice. 147 | 148 | 34 149 | 00:02:01,889 --> 00:02:06,149 150 | So I wish you the same kind of epiphany. 151 | 152 | 35 153 | 00:02:06,149 --> 00:02:07,929 154 | And I'm sure that by the end of this course, 155 | 156 | 36 157 | 00:02:07,929 --> 00:02:10,770 158 | you will feel like you are a better programmer. 159 | 160 | 37 161 | 00:02:12,300 --> 00:02:13,760 162 | One last thing... 163 | 164 | 38 165 | 00:02:15,110 --> 00:02:17,600 166 | Remember: programming should be fun! 167 | 168 | 39 169 | 00:02:17,600 --> 00:02:20,310 170 | I mean there is pleasure in programming, 171 | and 172 | 173 | 40 174 | 00:02:20,310 --> 00:02:22,420 175 | we should keep it this way. 176 | 177 | 41 178 | 00:02:22,420 --> 00:02:25,920 179 | So, have fun with functional programming. 180 | 181 | 42 182 | 00:02:25,920 --> 00:02:26,810 183 | And enjoy this course. 184 | 185 | -------------------------------------------------------------------------------- /OCaml_MOOC_W0_ALL/W0Hello_fr.srt: -------------------------------------------------------------------------------- 1 | 1 2 | 00:00:02,240 --> 00:00:03,500 3 | Bonjour. 4 | 5 | 2 6 | 00:00:03,500 --> 00:00:07,010 7 | Bienvenue à ce cours en ligne 8 | sur la programmation fonctionnelle en OCaml. 9 | 10 | 3 11 | 00:00:07,010 --> 00:00:09,580 12 | Mon nom est Xavier Leroy. 13 | 14 | 4 15 | 00:00:09,580 --> 00:00:12,580 16 | Je suis un chercheur, ici en France. 17 | 18 | 5 19 | 00:00:12,580 --> 00:00:18,050 20 | Et l'un des concepteurs et développeurs 21 | du langage OCaml, 22 | 23 | 6 24 | 00:00:18,050 --> 00:00:20,720 25 | que vous utiliserez pendant ce cours. 26 | 27 | 7 28 | 00:00:20,720 --> 00:00:23,170 29 | Ceci est le premier MOOC sur OCaml, 30 | 31 | 8 32 | 00:00:23,170 --> 00:00:30,539 33 | Cela signifie beaucoup pour moi 34 | et pour les autres développeurs d'OCaml. 35 | 36 | 9 37 | 00:00:30,539 --> 00:00:34,680 38 | Nous sommes donc ravis de voir un 39 | si grand nombre d'entre vous joindre ce cours. 40 | 41 | 10 42 | 00:00:34,680 --> 00:00:37,970 43 | Et nous sommes également très reconnaissants 44 | aux trois instructeurs, 45 | 46 | 11 47 | 00:00:37,970 --> 00:00:42,820 48 | et tous ceux qui ont participé 49 | à la mise en place de ce cours. 50 | 51 | 12 52 | 00:00:42,820 --> 00:00:46,710 53 | Si vous avez déjà certaines notions 54 | de programmation fonctionnelle, 55 | 56 | 13 57 | 00:00:46,710 --> 00:00:50,130 58 | J'espère, vous trouverez OCaml robuste, 59 | 60 | 14 61 | 00:00:50,130 --> 00:00:54,870 62 | et très adéquat à ce style de programmation. 63 | 64 | 15 65 | 00:00:54,870 --> 00:00:57,400 66 | Il possède beaucoup de domaines d'application, 67 | 68 | 16 69 | 00:00:57,400 --> 00:00:59,780 70 | comme des outils de vérification de logiciels, 71 | 72 | 17 73 | 00:00:59,780 --> 00:01:02,860 74 | l'analyse statique, la démonstration de théorèmes, 75 | 76 | 18 77 | 00:01:02,860 --> 00:01:05,460 78 | mais aussi dans la programmation web, 79 | 80 | 19 81 | 00:01:05,460 --> 00:01:06,500 82 | dans la programmation système, 83 | 84 | 20 85 | 00:01:06,500 --> 00:01:09,359 86 | dans le secteur financier, 87 | 88 | 21 89 | 00:01:09,359 --> 00:01:11,859 90 | ou la bio-informatique, 91 | 92 | 22 93 | 00:01:11,859 --> 00:01:14,159 94 | et de nombreux autres 95 | domaines d'application passionnants, 96 | 97 | 23 98 | 00:01:14,159 --> 00:01:18,560 99 | où OCaml est un très bon choix. 100 | 101 | 24 102 | 00:01:18,560 --> 00:01:22,280 103 | Mais si ceci est votre première exposition 104 | à la programmation fonctionnelle, 105 | 106 | 25 107 | 00:01:22,280 --> 00:01:24,329 108 | franchement, je vous envie. 109 | 110 | 26 111 | 00:01:24,329 --> 00:01:28,399 112 | Parce que cela me rappelle ma première expérience 113 | de programmation fonctionnelle, 114 | 115 | 27 116 | 00:01:28,399 --> 00:01:31,299 117 | C'était il y a très longtemps. 118 | 119 | 28 120 | 00:01:31,299 --> 00:01:34,530 121 | Et au début, c'était étrange comme sensation... 122 | 123 | 29 124 | 00:01:34,530 --> 00:01:39,590 125 | tout était légèrement différent de ce que 126 | je connaisais à l'époque de la programmation. 127 | 128 | 30 129 | 00:01:39,590 --> 00:01:43,900 130 | Mais après un moment, il y a eu comme un déclic, 131 | et je fut séduit 132 | 133 | 31 134 | 00:01:43,900 --> 00:01:50,310 135 | par l'élégance et à l'expressivité 136 | de ce style de programmation. 137 | 138 | 32 139 | 00:01:50,310 --> 00:01:55,509 140 | Tant et si bien que j'ai passé 141 | de nombreuses années à travailler sur OCaml. 142 | 143 | 33 144 | 00:01:55,509 --> 00:02:01,889 145 | Juste pour rendre la programmation fonctionnelle 146 | plus utilisable en pratique. 147 | 148 | 34 149 | 00:02:01,889 --> 00:02:06,149 150 | Je vous souhaite donc la même épiphanie. 151 | 152 | 35 153 | 00:02:06,149 --> 00:02:07,929 154 | Et je suis sûr que d'ici la fin de ce cours, 155 | 156 | 36 157 | 00:02:07,929 --> 00:02:10,770 158 | vous vous sentirez meilleur programmeur. 159 | 160 | 37 161 | 00:02:12,300 --> 00:02:13,760 162 | Une dernière chose... 163 | 164 | 38 165 | 00:02:15,110 --> 00:02:17,600 166 | Rappelez-vous : 167 | la programmation devrait être "fun" ! 168 | 169 | 39 170 | 00:02:17,600 --> 00:02:20,310 171 | Je veux dire : il y a du plaisir à programmer, 172 | 173 | 40 174 | 00:02:20,310 --> 00:02:22,420 175 | et nous ne devrions pas oublier cette joie. 176 | 177 | 41 178 | 00:02:22,420 --> 00:02:25,920 179 | Alors, amusez-vous bien 180 | avec la programmation fonctionnelle. 181 | 182 | 42 183 | 00:02:25,920 --> 00:02:26,810 184 | Et profitez de ce cours. 185 | -------------------------------------------------------------------------------- /OCaml_MOOC_W0_ALL/W0Hello_pt.srt: -------------------------------------------------------------------------------- 1 | 1 2 | 00:00:02,240 --> 00:00:03,500 3 | Olá. 4 | 5 | 2 6 | 00:00:03,500 --> 00:00:07,010 7 | Bem-vindo a este curso online 8 | sobre programação funcional em OCaml. 9 | 10 | 3 11 | 00:00:07,010 --> 00:00:09,580 12 | O meu nome é Xavier Leroy. 13 | 14 | 4 15 | 00:00:09,580 --> 00:00:12,580 16 | Sou investigador, aqui em França. 17 | 18 | 5 19 | 00:00:12,580 --> 00:00:18,050 20 | E um dos criadores e programador 21 | da linguagem OCaml, 22 | 23 | 6 24 | 00:00:18,050 --> 00:00:20,720 25 | que irão utilisar durante este curso. 26 | 27 | 7 28 | 00:00:20,720 --> 00:00:23,170 29 | Este é o primeiro MOOC sobre OCaml, 30 | 31 | 8 32 | 00:00:23,170 --> 00:00:30,539 33 | O que significa muito para mim 34 | et para os outros programadores de OCaml. 35 | 36 | 9 37 | 00:00:30,539 --> 00:00:34,680 38 | Estamos portanto entusiasmados de ver 39 | tantos inscritos neste curso. 40 | 41 | 10 42 | 00:00:34,680 --> 00:00:37,970 43 | Estamos igualmente muito reconhecidos 44 | aos três instrutores, 45 | 46 | 11 47 | 00:00:37,970 --> 00:00:42,820 48 | e a todos que participaram 49 | na elaboração deste curso. 50 | 51 | 12 52 | 00:00:42,820 --> 00:00:46,710 53 | Se possuem já algum conhecimento 54 | de programaçao funcional, 55 | 56 | 13 57 | 00:00:46,710 --> 00:00:50,130 58 | Verão, assim espero, que OCaml é robusto, 59 | 60 | 14 61 | 00:00:50,130 --> 00:00:54,870 62 | e bastante adequado a este estilo de programação. 63 | 64 | 15 65 | 00:00:54,870 --> 00:00:57,400 66 | Esta linguagem possui um vasto domínio de aplicação, 67 | 68 | 16 69 | 00:00:57,400 --> 00:00:59,780 70 | tais como ferramentas de verificação de software, 71 | 72 | 17 73 | 00:00:59,780 --> 00:01:02,860 74 | a análise estátitca, a demonstração de teoremas, 75 | 76 | 18 77 | 00:01:02,860 --> 00:01:05,460 78 | mas também a programação web, 79 | 80 | 19 81 | 00:01:05,460 --> 00:01:06,500 82 | programação de sistemas, 83 | 84 | 20 85 | 00:01:06,500 --> 00:01:09,359 86 | no sector financeiro, 87 | 88 | 21 89 | 00:01:09,359 --> 00:01:11,859 90 | ou na bio-informática, 91 | 92 | 22 93 | 00:01:11,859 --> 00:01:14,159 94 | entre vários outros 95 | domínios de aplicação apaixonantes, 96 | 97 | 23 98 | 00:01:14,159 --> 00:01:18,560 99 | para os quais OCaml é uma óptima escolha. 100 | 101 | 24 102 | 00:01:18,560 --> 00:01:22,280 103 | Mas se esta é a vossa primeira exposição 104 | à programação funcional, 105 | 106 | 25 107 | 00:01:22,280 --> 00:01:24,329 108 | invejo-vos, de verdade. 109 | 110 | 26 111 | 00:01:24,329 --> 00:01:28,399 112 | Porque tal faz-me recordar a minha primeira experiência 113 | de programação funcional. 114 | 115 | 27 116 | 00:01:28,399 --> 00:01:31,299 117 | Aconteceu há muito tempo. 118 | 119 | 28 120 | 00:01:31,299 --> 00:01:34,530 121 | E no início foi estranho como sensação... 122 | 123 | 29 124 | 00:01:34,530 --> 00:01:39,590 125 | tudo era ligeiramente diferente do que 126 | eu conhecia, nessa altura, sobre programação. 127 | 128 | 30 129 | 00:01:39,590 --> 00:01:43,900 130 | Mas após um instante, houve uma espécie de clique, 131 | e fiquei completamente seduzido 132 | 133 | 31 134 | 00:01:43,900 --> 00:01:50,310 135 | pela elegância e expressividade 136 | deste estilo de programção. 137 | 138 | 32 139 | 00:01:50,310 --> 00:01:55,509 140 | Tanto que após isso passei 141 | vários anos a trabalhar no OCaml. 142 | 143 | 33 144 | 00:01:55,509 --> 00:02:01,889 145 | Apenas para tornar a programação funcional 146 | mais utilizável na prática. 147 | 148 | 34 149 | 00:02:01,889 --> 00:02:06,149 150 | Desejo-vos assim a mesma epifania. 151 | 152 | 35 153 | 00:02:06,149 --> 00:02:07,929 154 | Tenho a certeza que daqui até ao fim do curso, 155 | 156 | 36 157 | 00:02:07,929 --> 00:02:10,770 158 | irão se sentir melhores programadores. 159 | 160 | 37 161 | 00:02:12,300 --> 00:02:13,760 162 | Uma última nota... 163 | 164 | 38 165 | 00:02:15,110 --> 00:02:17,600 166 | Lembrem-se: 167 | a programação deve ser "fun"! 168 | 169 | 39 170 | 00:02:17,600 --> 00:02:20,310 171 | Isto é: deve haver prazer em programar, 172 | 173 | 40 174 | 00:02:20,310 --> 00:02:22,420 175 | e não devemos esquecer esta alegria. 176 | 177 | 41 178 | 00:02:22,420 --> 00:02:25,920 179 | Portanto, divirtam-se 180 | com a programação funcional. 181 | 182 | 42 183 | 00:02:25,920 --> 00:02:26,810 184 | E disfrutem deste curso. 185 | -------------------------------------------------------------------------------- /OCaml_MOOC_W0_ALL/W0_S6.srt: -------------------------------------------------------------------------------- 1 | 1 2 | 00:00:00,120 --> 00:00:00,860 3 | Welcome back, 4 | 5 | 2 6 | 00:00:00,860 --> 00:00:02,969 7 | this is the final sequence of the first week. 8 | 9 | 3 10 | 00:00:02,969 --> 00:00:06,209 11 | We will talk about some of the ressources. 12 | 13 | 4 14 | 00:00:06,209 --> 00:00:07,939 15 | that you have at your disposal for learning now. 16 | 17 | 5 18 | 00:00:07,939 --> 00:00:11,519 19 | But let me start by telling you that 20 | this course is really self-contained. 21 | 22 | 6 23 | 00:00:11,519 --> 00:00:16,980 24 | You will not need anything more than 25 | what is provided in the learning environment. 26 | 27 | 7 28 | 00:00:16,980 --> 00:00:25,160 29 | But anyway, for curious minds, there are quite 30 | a lot of ressources, available in the web and for free. 31 | 32 | 8 33 | 00:00:25,160 --> 00:00:32,100 34 | The first pointer I would like you to follow is the http://ocaml.org/ community website. 35 | 36 | 9 37 | 00:00:32,140 --> 00:00:37,980 38 | This is a website that evolved over the last 39 | years to bring together the community. 40 | 41 | 10 42 | 00:00:37,980 --> 00:00:41,030 43 | You will have documentation and information 44 | about all the available packages, 45 | 46 | 11 47 | 00:00:41,030 --> 00:00:46,940 48 | news, tutorials, a lot of things 49 | that are useful to be aware of, 50 | 51 | 12 52 | 00:00:46,940 --> 00:00:48,199 53 | even if you don't need it for the course. 54 | 55 | 13 56 | 00:00:48,199 --> 00:00:52,690 57 | You can get general help 58 | on forums and mailing-lists. 59 | 60 | 14 61 | 00:00:52,690 --> 00:00:54,480 62 | Let me start by saying very clearly, 63 | 64 | 15 65 | 00:00:54,480 --> 00:01:00,019 66 | that, during this MOOC, we really suggest you 67 | to use the forum on the FUN platform, 68 | 69 | 16 70 | 00:01:00,019 --> 00:01:01,280 71 | right in the learning environment, 72 | 73 | 17 74 | 00:01:01,280 --> 00:01:04,000 75 | for the reason that you will find other people like you, 76 | 77 | 18 78 | 00:01:04,000 --> 00:01:06,570 79 | which are progressing at a similar pace. 80 | 81 | 19 82 | 00:01:06,570 --> 00:01:10,000 83 | There are teaching assistants 84 | that know exactly what is going on in this course 85 | 86 | 20 87 | 00:01:10,000 --> 00:01:12,690 88 | and are specifically here to help. 89 | 90 | 21 91 | 00:01:12,690 --> 00:01:16,620 92 | The other people are going to use exactly 93 | the same environment. 94 | 95 | 22 96 | 00:01:16,620 --> 00:01:18,330 97 | You will have support with the learning platform. 98 | 99 | 23 100 | 00:01:18,330 --> 00:01:21,900 101 | So this is really the first place 102 | where you have to go. 103 | 104 | 24 105 | 00:01:21,900 --> 00:01:25,720 106 | And, in general, you should not need 107 | to have anything else to follow this MOOC. 108 | 109 | 25 110 | 00:01:25,720 --> 00:01:31,040 111 | But if you really want to have a look, 112 | there are interesting mailing-lists to explore. 113 | 114 | 26 115 | 00:01:31,040 --> 00:01:35,540 116 | There is the ocaml-beginners group on Yahoo groups. 117 | 118 | 27 119 | 00:01:35,540 --> 00:01:42,660 120 | There is an official ocaml-list still ran by INRIA, 121 | 122 | 28 123 | 00:01:42,660 --> 00:01:46,580 124 | where confirmed OCaml programmers 125 | go to post questions, post information. 126 | 127 | 29 128 | 00:01:46,580 --> 00:01:49,390 129 | But this is an advanced mailing-list. 130 | 131 | 30 132 | 00:01:49,390 --> 00:01:55,470 133 | As always the netiquette is the same, 134 | search archives before asking a question. 135 | 136 | 31 137 | 00:01:55,470 --> 00:02:00,610 138 | Don't ask elementary questions 139 | on the advanced mailing list. 140 | 141 | 32 142 | 00:02:00,610 --> 00:02:03,490 143 | Start with the MOOC environment first. 144 | 145 | 33 146 | 00:02:03,490 --> 00:02:05,980 147 | But you also have books and manuals available. 148 | 149 | 34 150 | 00:02:05,980 --> 00:02:10,390 151 | There are many ressources, very valuable ones, 152 | available for free online. 153 | 154 | 35 155 | 00:02:10,390 --> 00:02:14,680 156 | The first one is the OCaml user manual. 157 | 158 | 36 159 | 00:02:14,680 --> 00:02:17,930 160 | This comes from the designers of the language. 161 | 162 | 37 163 | 00:02:17,930 --> 00:02:24,829 164 | The lattest and always up-to-date version 165 | is available exactly from this link here. 166 | 167 | 38 168 | 00:02:24,829 --> 00:02:27,780 169 | Of course, this is not a tutorial. 170 | 171 | 39 172 | 00:02:27,780 --> 00:02:29,489 173 | It's a user manual. 174 | 175 | 40 176 | 00:02:29,489 --> 00:02:35,669 177 | If you really want to have the precise specification 178 | of each feature of the language that the reference point. 179 | 180 | 41 181 | 00:02:35,670 --> 00:02:38,400 182 | And there is a book which was written in 2000. 183 | 184 | 42 185 | 00:02:38,400 --> 00:02:41,200 186 | ---yes, fifteen years ago, but still quite valuable--- 187 | 188 | 43 189 | 00:02:41,200 --> 00:02:45,200 190 | from Emmanuel Chailloux, 191 | Pascal Manoury, and Bruno Pagano. 192 | 193 | 44 194 | 00:02:45,249 --> 00:02:47,989 195 | It was originally written in French, 196 | then translated into English. 197 | 198 | 45 199 | 00:02:47,989 --> 00:02:54,709 200 | It is vailable for free, again from this link here. 201 | 202 | 46 203 | 00:02:54,709 --> 00:02:58,249 204 | It doesn't cover the most recent 205 | advances in the language 206 | 207 | 47 208 | 00:02:58,249 --> 00:03:01,349 209 | but for the introduction, it is really beautiful. 210 | 211 | 48 212 | 00:03:01,349 --> 00:03:05,200 213 | And if you really want to know more about 214 | the theory behind this, 215 | 216 | 49 217 | 00:03:05,200 --> 00:03:08,810 218 | I would strongly recommend you have a look to 219 | 220 | 50 221 | 00:03:08,810 --> 00:03:12,600 222 | the course notes by Didier Remy from 223 | "Applied Semantics Summer School" 224 | 225 | 51 226 | 00:03:12,600 --> 00:03:14,989 227 | which was also held in the year 2000. 228 | 229 | 52 230 | 00:03:14,989 --> 00:03:18,800 231 | This gives you really the understanding of 232 | how the system works inside, 233 | 234 | 53 235 | 00:03:18,800 --> 00:03:21,599 236 | from a theoretical point of view. 237 | 238 | 54 239 | 00:03:21,599 --> 00:03:27,739 240 | But then, if you look for more recent ressources, 241 | there are many which are non free, 242 | 243 | 55 244 | 00:03:27,739 --> 00:03:31,269 245 | there are quite a few books available, 246 | in English and in French. 247 | 248 | 56 249 | 00:03:31,269 --> 00:03:36,169 250 | Again, go to the ocaml.org community website, 251 | 252 | 57 253 | 00:03:36,169 --> 00:03:40,590 254 | where there is a comprehensive list of books. 255 | 256 | 58 257 | 00:03:40,590 --> 00:03:47,560 258 | So in conclusion, after this first week, 259 | you should be setup to enjoy the course. 260 | 261 | 59 262 | 00:03:47,560 --> 00:03:49,169 263 | You have discovered the exercise environment, 264 | 265 | 60 266 | 00:03:49,169 --> 00:03:52,760 267 | you know where we are coming from. 268 | 269 | 61 270 | 00:03:52,760 --> 00:03:59,000 271 | And we are really looking forward seeing you next week, 272 | to start the real technical journey with us. 273 | 274 | -------------------------------------------------------------------------------- /OCaml_MOOC_W0_ALL/W0_S6_fr.srt: -------------------------------------------------------------------------------- 1 | 1 2 | 00:00:00,120 --> 00:00:00,860 3 | Re-bonjour, 4 | 5 | 2 6 | 00:00:00,860 --> 00:00:02,969 7 | voici la dernière séquence de la première semaine. 8 | 9 | 3 10 | 00:00:02,969 --> 00:00:06,209 11 | Nous allons parler de quelques-unes des ressources que 12 | 13 | 4 14 | 00:00:06,209 --> 00:00:07,939 15 | vous avez à votre disposition pour apprendre davantage. 16 | 17 | 5 18 | 00:00:07,939 --> 00:00:11,519 19 | Mais laissez-moi commencer en vous disant qu'en fait 20 | ce cours se suffit vraiment à lui-même. 21 | 22 | 6 23 | 00:00:11,519 --> 00:00:16,980 24 | Vous n'aurez besoin de rien de plus que ce qui est 25 | fourni dans l'environnement d'apprentissage. 26 | 27 | 7 28 | 00:00:16,980 --> 00:00:25,160 29 | Ceci dit, pour les esprits curieux, il y a pas mal de 30 | ressources, disponibles sur le web et gratuitement. 31 | 32 | 8 33 | 00:00:25,160 --> 00:00:32,100 34 | Le premier pointeur que je vous recommande est 35 | http://ocaml.org/, le site de la communauté. 36 | 37 | 9 38 | 00:00:32,140 --> 00:00:37,980 39 | C'est un site web qui a beaucoup évolué au cours 40 | des dernières années pour rassembler la communauté. 41 | 42 | 10 43 | 00:00:37,980 --> 00:00:41,030 44 | Vous y trouverez de la documentation et de 45 | l'information sur tous les paquets disponibles, 46 | 47 | 11 48 | 00:00:41,030 --> 00:00:46,940 49 | des nouvelles, des tutoriels, beaucoup de choses 50 | qui sont utiles pour être au courant, 51 | 52 | 12 53 | 00:00:46,940 --> 00:00:48,199 54 | même si vous n'en avez pas besoin pour le cours. 55 | 56 | 13 57 | 00:00:48,199 --> 00:00:52,690 58 | Vous pouvez obtenir de l'aide générale 59 | sur les forums et les listes de diffusion. 60 | 61 | 14 62 | 00:00:52,690 --> 00:00:54,480 63 | Permettez-moi de commencer par dire très clairement, 64 | 65 | 15 66 | 00:00:54,480 --> 00:01:00,019 67 | qu'au cours de ce MOOC, nous vous suggérons vraiment 68 | d'utiliser le forum sur la plate-forme de FUN, 69 | 70 | 16 71 | 00:01:00,019 --> 00:01:01,280 72 | directement dans l'environnement d'apprentissage, 73 | 74 | 17 75 | 00:01:01,280 --> 00:01:04,000 76 | pour la raison que vous trouverez 77 | d'autres gens comme vous, 78 | 79 | 18 80 | 00:01:04,000 --> 00:01:06,570 81 | qui progressent à un rythme similaire. 82 | 83 | 19 84 | 00:01:06,570 --> 00:01:10,000 85 | Il y a des assistants d'enseignement qui savent 86 | exactement ce qui se passe dans ce cours 87 | 88 | 20 89 | 00:01:10,000 --> 00:01:12,690 90 | et sont ici spécialement pour vous aider. 91 | 92 | 21 93 | 00:01:12,690 --> 00:01:16,620 94 | Les autres personnes vont utiliser 95 | exactement le même environnement. 96 | 97 | 22 98 | 00:01:16,620 --> 00:01:18,330 99 | Vous aurez aussi de l'aide avec 100 | la plate-forme d'apprentissage. 101 | 102 | 23 103 | 00:01:18,330 --> 00:01:21,900 104 | Donc c'est vraiment le premier endroit où aller. 105 | 106 | 24 107 | 00:01:21,900 --> 00:01:25,720 108 | Et en général vous ne devriez avoir 109 | besoin de rien d'autre que ce MOOC. 110 | 111 | 25 112 | 00:01:25,720 --> 00:01:31,040 113 | Mais si vous voulez vraiment y jeter un oeil, 114 | il y a des listes de diffusion intéressantes à explorer. 115 | 116 | 26 117 | 00:01:31,040 --> 00:01:35,540 118 | Il y a le groupe ocaml-beginners 119 | sur Yahoo Groups. 120 | 121 | 27 122 | 00:01:35,540 --> 00:01:42,660 123 | Il y a une liste officielle ocaml-list gérée par INRIA, 124 | 125 | 28 126 | 00:01:42,660 --> 00:01:46,580 127 | où des programmeurs OCaml confirmés vont pour 128 | poster des questions, de l'information, 129 | 130 | 29 131 | 00:01:46,580 --> 00:01:49,390 132 | mais c'est une liste de diffusion 133 | pour utilisateur avancé. 134 | 135 | 30 136 | 00:01:49,390 --> 00:01:55,470 137 | Comme toujours, la nétiquette est la même, chercher 138 | d'abord dans les archives avant de poser une question. 139 | 140 | 31 141 | 00:01:55,470 --> 00:02:00,610 142 | Ne posez pas de question élémentaire 143 | sur la liste de diffusion avancée. 144 | 145 | 32 146 | 00:02:00,610 --> 00:02:03,490 147 | Commencez en premier par l'environnement MOOC. 148 | 149 | 33 150 | 00:02:03,490 --> 00:02:05,980 151 | Mais vous avez aussi des livres 152 | et manuels à votre disposition. 153 | 154 | 34 155 | 00:02:05,980 --> 00:02:10,390 156 | Il y a de nombreuses ressources, qui sont très valables 157 | et disponibles gratuitement en ligne. 158 | 159 | 35 160 | 00:02:10,390 --> 00:02:14,680 161 | La première est le manuel d'utilisation d'OCaml. 162 | 163 | 36 164 | 00:02:14,680 --> 00:02:17,930 165 | Il provient des concepteurs même du langage. 166 | 167 | 37 168 | 00:02:17,930 --> 00:02:24,829 169 | La dernière version, toujours à jour, 170 | est disponible exactement sur le lien ici. 171 | 172 | 38 173 | 00:02:24,829 --> 00:02:27,780 174 | Bien sûr, ce n'est pas un tutoriel. 175 | 176 | 39 177 | 00:02:27,780 --> 00:02:29,489 178 | C'est un manuel d'utilisation. 179 | 180 | 40 181 | 00:02:29,489 --> 00:02:35,669 182 | Si vous voulez vraiment avoir la spécification précise 183 | de chaque trait du langage, c'est le point de référence. 184 | 185 | 41 186 | 00:02:35,670 --> 00:02:38,400 187 | Et il y a un livre qui a été écrit en 2000, 188 | 189 | 42 190 | 00:02:38,400 --> 00:02:41,200 191 | --- eh oui, il y a quinze ans --- 192 | mais encore très valable, 193 | 194 | 43 195 | 00:02:41,200 --> 00:02:45,200 196 | par Emmanuel Chailloux, Pascal Manoury et Bruno Pagano. 197 | 198 | 44 199 | 00:02:45,249 --> 00:02:47,989 200 | Il a été écrit à l'origine en français, 201 | puis traduit en anglais. 202 | 203 | 45 204 | 00:02:47,989 --> 00:02:54,709 205 | Il est disponible gratuitement, là encore, 206 | à partir de ce lien : 207 | 208 | 46 209 | 00:02:54,709 --> 00:02:58,249 210 | Il ne couvre pas les avancées 211 | les plus récentes du langage 212 | 213 | 47 214 | 00:02:58,249 --> 00:03:01,349 215 | mais pour une introduction, il est vraiment bon. 216 | 217 | 48 218 | 00:03:01,349 --> 00:03:05,200 219 | Et si vous voulez vraiment en savoir plus 220 | sur la théorie derrière tout cela, 221 | 222 | 49 223 | 00:03:05,200 --> 00:03:08,810 224 | je vous recommanderais de jeter un oeil sur 225 | 226 | 50 227 | 00:03:08,810 --> 00:03:12,600 228 | les notes de cours de Didier Remy à 229 | « Applied Semantics Summer School » 230 | 231 | 51 232 | 00:03:12,600 --> 00:03:14,989 233 | qui s'est également tenue en l'an 2000. 234 | 235 | 52 236 | 00:03:14,989 --> 00:03:18,800 237 | Cela vous donne vraiment la compréhension du 238 | fonctionnement interne du système, 239 | 240 | 53 241 | 00:03:18,800 --> 00:03:21,599 242 | d'un point de vue théorique. 243 | 244 | 54 245 | 00:03:21,599 --> 00:03:27,739 246 | Mais ensuite, si vous cherchez des ressources plus 247 | récentes, il y en a beaucoup qui ne sont pas gratuites, 248 | 249 | 55 250 | 00:03:27,739 --> 00:03:31,269 251 | il y a pas mal de livres disponibles 252 | en anglais et en français. 253 | 254 | 56 255 | 00:03:31,269 --> 00:03:36,169 256 | Là encore, allez sur le site web de la communauté, 257 | http://ocaml.org/ 258 | 259 | 57 260 | 00:03:36,169 --> 00:03:40,590 261 | où il y a une liste complète de livres. 262 | 263 | 58 264 | 00:03:40,590 --> 00:03:47,560 265 | Donc, en conclusion, après cette première semaine, vous 266 | devriez avoir tout ce qu'il faut pour profiter du cours. 267 | 268 | 59 269 | 00:03:47,560 --> 00:03:49,169 270 | Vous avez découvert l'environnement d'exercice, 271 | 272 | 60 273 | 00:03:49,169 --> 00:03:52,760 274 | vous savez d'où nous venons. 275 | 276 | 61 277 | 00:03:52,760 --> 00:03:59,000 278 | Et nous sommes vraiment impatients 279 | de vous voir la semaine prochaine pour commencer 280 | le véritable voyage technique avec nous. 281 | -------------------------------------------------------------------------------- /OCaml_MOOC_W0_ALL/W0_S6_pt.srt: -------------------------------------------------------------------------------- 1 | 1 2 | 00:00:00,120 --> 00:00:00,860 3 | Olá de novo, 4 | 5 | 2 6 | 00:00:00,860 --> 00:00:02,969 7 | esta é a ultima sequência desta primeira semana. 8 | 9 | 3 10 | 00:00:02,969 --> 00:00:06,209 11 | Vamos falar de alguns recursos 12 | 13 | 4 14 | 00:00:06,209 --> 00:00:07,939 15 | que tem ao seu dispor para progredir na aprendizagem. 16 | 17 | 5 18 | 00:00:07,939 --> 00:00:11,519 19 | Mas deixe-me começar por dizer que na verdade 20 | este curso é auto-suficiente. 21 | 22 | 6 23 | 00:00:11,519 --> 00:00:16,980 24 | Não precisará de mais nada para além do 25 | que está disponível no ambiente de aprendizagem. 26 | 27 | 7 28 | 00:00:16,980 --> 00:00:25,160 29 | Dito isto, para o espírito inquisitivo,há uma variedade 30 | grande de recursos, disponíveis gratuitamente e na web. 31 | 32 | 8 33 | 00:00:25,160 --> 00:00:32,100 34 | O primeiro apontador que vos recomendo é 35 | http://ocaml.org/, o site da comunidade. 36 | 37 | 9 38 | 00:00:32,140 --> 00:00:37,980 39 | É um site que evoluiu muito estes últimos anos, 40 | para agrupar a comunidade. 41 | 42 | 10 43 | 00:00:37,980 --> 00:00:41,030 44 | Encontrará ali documentação e informações 45 | sobre os pacotes de software disponíveis, 46 | 47 | 11 48 | 00:00:41,030 --> 00:00:46,940 49 | novidades, tutoriais, e muito mais coisas 50 | úteis para estar a par, 51 | 52 | 12 53 | 00:00:46,940 --> 00:00:48,199 54 | mesmo se estas não são necessárias para esta aula. 55 | 56 | 13 57 | 00:00:48,199 --> 00:00:52,690 58 | Poderá obter ajuda genérica nos 59 | fóruns e listas de difusão. 60 | 61 | 14 62 | 00:00:52,690 --> 00:00:54,480 63 | Permita-me que comece por dizer muito claramente, 64 | 65 | 15 66 | 00:00:54,480 --> 00:01:00,019 67 | que durante este MOOC, sugerimo-vos que utilize o 68 | forum da plataforma FUN, 69 | 70 | 16 71 | 00:01:00,019 --> 00:01:01,280 72 | directamente a partir do ambiente de aprendizagem, 73 | 74 | 17 75 | 00:01:01,280 --> 00:01:04,000 76 | pela razão que encontrarão ali gente como vocês, 77 | 78 | 18 79 | 00:01:04,000 --> 00:01:06,570 80 | que progridem num ritmo similar. 81 | 82 | 19 83 | 00:01:06,570 --> 00:01:10,000 84 | Há assistente de aulas que sabem exactamente 85 | o que está acontecendo nestas aulas 86 | 87 | 20 88 | 00:01:10,000 --> 00:01:12,690 89 | e que estão aqui precisamente para vos ajudar. 90 | 91 | 21 92 | 00:01:12,690 --> 00:01:16,620 93 | As outras pessoas vão utilizar exactamente o mesmo ambiente. 94 | 95 | 22 96 | 00:01:16,620 --> 00:01:18,330 97 | Terá igualmente ajuda com a 98 | plataforma de aprendizagem. 99 | 100 | 23 101 | 00:01:18,330 --> 00:01:21,900 102 | Por isso, é mesmo o primeiro local por procurar. 103 | 104 | 24 105 | 00:01:21,900 --> 00:01:25,720 106 | Em regra geral, não deverá precisar de 107 | mais nada sem ser este MOOC. 108 | 109 | 25 110 | 00:01:25,720 --> 00:01:31,040 111 | Mas se pretende olhar para além 112 | há listas de difusão interessantes por explorar. 113 | 114 | 26 115 | 00:01:31,040 --> 00:01:35,540 116 | Há o grupo ocaml-beginners 117 | no Yahoo Groups. 118 | 119 | 27 120 | 00:01:35,540 --> 00:01:42,660 121 | Há uma lista oficial ocaml-list gerida pelo INRIA, 122 | 123 | 28 124 | 00:01:42,660 --> 00:01:46,580 125 | onde os programadores confirmados colocam as 126 | suas questões e pedidos de informação, 127 | 128 | 29 129 | 00:01:46,580 --> 00:01:49,390 130 | mas é uma lista de difusão para 131 | utilizadores experientes. 132 | 133 | 30 134 | 00:01:49,390 --> 00:01:55,470 135 | Como sempre, a netiqueta é a mesma, procurar 136 | nos arquivos antes de colocar a questão. 137 | 138 | 31 139 | 00:01:55,470 --> 00:02:00,610 140 | Não coloque questões elementares na lista de 141 | difusão para utilizadores confirmados. 142 | 143 | 32 144 | 00:02:00,610 --> 00:02:03,490 145 | Comece antes pelo ambiente MOOC. 146 | 147 | 33 148 | 00:02:03,490 --> 00:02:05,980 149 | Mas há igualmente livros e manuais ao vosso dispor. 150 | 151 | 34 152 | 00:02:05,980 --> 00:02:10,390 153 | Existam numerosos recursos, que são preciosos 154 | e gratuitamente disponíveis online. 155 | 156 | 35 157 | 00:02:10,390 --> 00:02:14,680 158 | O primeiro é o manual de utilização de OCaml. 159 | 160 | 36 161 | 00:02:14,680 --> 00:02:17,930 162 | Provém dos próprios autores da linguagem OCaml. 163 | 164 | 37 165 | 00:02:17,930 --> 00:02:24,829 166 | A última versão, sempre actualizada, 167 | está disponível neste preciso link. 168 | 169 | 38 170 | 00:02:24,829 --> 00:02:27,780 171 | Claro, não é um tutorial. 172 | 173 | 39 174 | 00:02:27,780 --> 00:02:29,489 175 | É um manual de utilização. 176 | 177 | 40 178 | 00:02:29,489 --> 00:02:35,669 179 | Se quer ter a especificação rigoroso de cada 180 | aspecto da linguagem, é o ponto de referência. 181 | 182 | 41 183 | 00:02:35,670 --> 00:02:38,400 184 | E há um livro, escrito em 2000, 185 | 186 | 42 187 | 00:02:38,400 --> 00:02:41,200 188 | --- isso mesmo, há quinze anos --- 189 | mas ainda assim sempre muito pertinente, 190 | 191 | 43 192 | 00:02:41,200 --> 00:02:45,200 193 | por Emmanuel Chailloux, Pascal Manoury e Bruno Pagano. 194 | 195 | 44 196 | 00:02:45,249 --> 00:02:47,989 197 | Foi escrito originalmente em francês 198 | e depois traduzido em inglês. 199 | 200 | 45 201 | 00:02:47,989 --> 00:02:54,709 202 | Está disponível gratuitamente, aqui também, 203 | via este link : 204 | 205 | 46 206 | 00:02:54,709 --> 00:02:58,249 207 | Não cobre os avanços recentes da linguagem 208 | 209 | 47 210 | 00:02:58,249 --> 00:03:01,349 211 | mas para uma introdução, é óptimo. 212 | 213 | 48 214 | 00:03:01,349 --> 00:03:05,200 215 | E se pretende ainda assim saber mais sobre a 216 | teoria que fundamenta o edifício todo, 217 | 218 | 49 219 | 00:03:05,200 --> 00:03:08,810 220 | recomendo-vos de dar uma vista de olhos 221 | 222 | 50 223 | 00:03:08,810 --> 00:03:12,600 224 | na sebenta de Didier Remy para a 225 | « Applied Semantics Summer School » 226 | 227 | 51 228 | 00:03:12,600 --> 00:03:14,989 229 | que também teve lugar no ano 2000. 230 | 231 | 52 232 | 00:03:14,989 --> 00:03:18,800 233 | Isto dá-vos realmente um entendimento do 234 | funcionamento interno do sistema, 235 | 236 | 53 237 | 00:03:18,800 --> 00:03:21,599 238 | de uma ponto de vista teórico. 239 | 240 | 54 241 | 00:03:21,599 --> 00:03:27,739 242 | Mas se entretanto procura recursos mais recentes, 243 | muitas existam mas não são sempre gratuitas, 244 | 245 | 55 246 | 00:03:27,739 --> 00:03:31,269 247 | há vários livros disponíveis em inglês e francês. 248 | 249 | 56 250 | 00:03:31,269 --> 00:03:36,169 251 | Mais uma vez, veja o site da comunidade, 252 | http://ocaml.org/ 253 | 254 | 57 255 | 00:03:36,169 --> 00:03:40,590 256 | onde encontrará uma lista completa dos livros. 257 | 258 | 58 259 | 00:03:40,590 --> 00:03:47,560 260 | Assim, concluindo, após esta primeira semana, deverá 261 | ter o que necessita para aproveita bem este curso. 262 | 263 | 59 264 | 00:03:47,560 --> 00:03:49,169 265 | Descobriu o ambiente para os exercícios, 266 | 267 | 60 268 | 00:03:49,169 --> 00:03:52,760 269 | Sabe de onde somos. 270 | 271 | 61 272 | 00:03:52,760 --> 00:03:59,000 273 | E estamos realment ansiosos 274 | de vos ver na próxima semana para começar 275 | a autentica viagem técnica consigo. 276 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/Exercise/W1_S3_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | INTEGER IDENTIFIERS (2/2 points) 3 | Suppose that a variable x exists and is an integer. 4 | 5 | Define a variable x_power_8 that uses three multiplications to calculate x to the power of 8. The only function you are allowed to call is the ( * ) operator. 6 | 7 | Hint: use auxiliary variables. 8 | 9 | THE GIVEN PRELUDE 10 | 11 | let x = Random.int 9 + 1 (* not 0 *) 12 | *) 13 | 14 | 15 | let x_power_8 = 16 | let a = x * x in 17 | let b = a * a in 18 | b * b;; 19 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/Exercise/W1_S3_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | STRING IDENTIFIERS (2/2 points) 3 | Suppose that a variable word exists and is a string. 4 | 5 | Define a variable sentence that uses 5 string concatenations to create a string containing 9 times word, separated by commas (','). 6 | 7 | This time, experiment with defining local let ... ins to store the partial results. 8 | *) 9 | 10 | let sentence = 11 | let a = word ^ "," in 12 | let b = a ^ a in 13 | let c = b ^ b in 14 | let d =c ^ c in 15 | d ^ word;; 16 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/Exercise/W1_S4_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | SIMPLE FUNCTIONS OVER INTEGERS (20/20 points) 3 | Let's define two functions working with integers: 4 | 5 | multiple_of that takes two integer parameters, n and d, and determines whether n is a multiple of d. The function must return a boolean value. This function can be written without recursion. Look at the operators defined on integers in sequence 1. 6 | integer_square_root that calculates the integer square root of a positive integer n, that is the largest integer r such that r * r <= n. Hint: you may use floating point arithmetic, but don't forget that you have to convert explicitely between float and int. 7 | *) 8 | 9 | let multiple_of n d = 10 | (n mod d) = 0;; 11 | 12 | let integer_square_root n = 13 | let r = sqrt (float_of_int n) in 14 | int_of_float r;; 15 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/Exercise/W1_S4_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | SIMPLE FUNCTIONS OVER STRINGS (12/12 points) 3 | Let's define two functions working with strings: 4 | 5 | last_character that returns the last character of a string, assuming that the string argument is not empty; 6 | string_of_bool that converts a boolean value to its string representation. 7 | *) 8 | 9 | let last_character str = 10 | let size = String.length str in 11 | String.get str (size - 1);; 12 | 13 | let string_of_bool truth = 14 | if truth = true then "true" else "false";; 15 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/Exercise/W1_S5_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | PRIME NUMBERS (30/30 points) 3 | Let's define some usual arithmetical functions. 4 | 5 | gcd that takes two non-negative integers n and m, and that returns the greatest common divisor of n and m, following Euclid's algorithm. 6 | multiple_upto : int -> int -> bool that takes two non-negative integers n and r, and that tells whether n admits at least one divisor between 2 and r, inclusive. In other words that there exists a number d >= 2 and <= r, such that the remainder of the division of n by d is zero. 7 | is_prime a takes a non-negative integer n and checks whether it is a prime number. 8 | Important note: You can assume that both integer_square_root and multiple_of exist, and that they are correct answers to the Simple functions over integers exercise from the previous sequence. 9 | 10 | Once is_prime works, you can try writing a new version of it which is self-contained (that contains all definitions of auxiliary functions as locally defined functions). 11 | *) 12 | 13 | let rec gcd n m = 14 | if (n < m) 15 | then (if (multiple_of m n) 16 | then n 17 | else (gcd n (m - n))) 18 | else gcd m n;; 19 | 20 | let rec multiple_upto n r = 21 | if (r > 1) 22 | then (if (n mod r = 0) 23 | then true 24 | else (multiple_upto n (r - 1))) 25 | else false;; 26 | 27 | let is_prime n = 28 | if (n = 1) 29 | then false 30 | else (let max = integer_square_root n in 31 | (not (multiple_upto n max)));; 32 | 33 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/OCaml_MOOC_W1_S0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W1_ALL/OCaml_MOOC_W1_S0.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/OCaml_MOOC_W1_S1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W1_ALL/OCaml_MOOC_W1_S1.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/OCaml_MOOC_W1_S2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W1_ALL/OCaml_MOOC_W1_S2.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/OCaml_MOOC_W1_S3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W1_ALL/OCaml_MOOC_W1_S3.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/OCaml_MOOC_W1_S4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W1_ALL/OCaml_MOOC_W1_S4.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/OCaml_MOOC_W1_S5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W1_ALL/OCaml_MOOC_W1_S5.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/application.ml: -------------------------------------------------------------------------------- 1 | String.get "abcd" 2;; 2 | 3 | String.get ("Hello, " ^ "World") (5-2);; 4 | 5 | String.get (string_of_int 65) (int_of_string "0");; 6 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/booleans.ml: -------------------------------------------------------------------------------- 1 | true && true;; 2 | 3 | false || true;; 4 | 5 | true && not (false || true);; 6 | 7 | 1 < 7;; 8 | 9 | 5.0 > "hello";; 10 | 11 | (7.56 <= 8e32) && (6 > -3);; 12 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/char.ml: -------------------------------------------------------------------------------- 1 | Char.code 'A';; 2 | 3 | Char.code '\122';; 4 | 5 | Char.chr 65;; 6 | 7 | Char.chr (Char.code 'B');; 8 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/errors.ml: -------------------------------------------------------------------------------- 1 | 3*(4+1)-7;; 2 | 3 | 17 +;; 4 | 5 | 42 + "hello";; 6 | 7 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/float.ml: -------------------------------------------------------------------------------- 1 | 3.0 +. 0.01;; 2 | 3 | 2e-4 *. 0.1;; 4 | 5 | 2 + 3.0;; 6 | 7 | 4 *. 56;; 8 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/functions.ml: -------------------------------------------------------------------------------- 1 | let f x = x+1;; (* global definition *) 2 | f 17;; 3 | 4 | let g y = 2*y (* local definition *) 5 | in g 42;; 6 | 7 | f f 1;; 8 | 9 | (f f) 1;; 10 | 11 | f (f 1);; 12 | 13 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/global.ml: -------------------------------------------------------------------------------- 1 | let x = 2+3;; 2 | 3 | let y = 2*x;; 4 | 5 | let x = 42;; 6 | 7 | y;; 8 | 9 | x;; 10 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/if.ml: -------------------------------------------------------------------------------- 1 | if 1<2 then 6+7 else 67/23;; 2 | 3 | if 6=8 then 1 else 77.5;; 4 | 5 | (if 6=3+3 then 3<4 else 8 > 7) && 67.8 > 33.1;; 6 | 7 | if (if 1=1 then 2=2 else 4.0 > 3.2) then 2<3 else 3<2;; 8 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/integers.ml: -------------------------------------------------------------------------------- 1 | 2+3*5;; 2 | 3 | 5/2;; 4 | 5 | -5 mod 3;; 6 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/lexicalscoping.ml: -------------------------------------------------------------------------------- 1 | (* with local definitions *) 2 | let f x = x+1 in 3 | let g y = f (f y) in 4 | let f x = 2*x in 5 | g 5;; 6 | 7 | (* with global definitions *) 8 | let f x = x+1;; 9 | let g y = f (f y);; 10 | let f x = 2*x;; 11 | g 5;; 12 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/local.ml: -------------------------------------------------------------------------------- 1 | let x = 4+5 in 2*x;; 2 | x;; 3 | let x = 17;; 4 | x;; 5 | let y = x+1 in y/3;; 6 | 7 | let x = 4 in 8 | let y = x+1 in 9 | let x = 2*y in x;; 10 | 11 | let x = 4 in 12 | (let x = 17 in x+1) + x;; 13 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/mutual.ml: -------------------------------------------------------------------------------- 1 | let rec even x = if x=0 then true else odd (x-1);; 2 | 3 | let rec even x = if x=0 then true else odd (x-1) 4 | and odd x = if x=0 then false else even (x-1);; 5 | 6 | even 17;; 7 | even 10;; 8 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/polymorph.ml: -------------------------------------------------------------------------------- 1 | 12 > 56.1;; 2 | 3 | (73>42) && (1e10>0.1) && ('B'>'A');; 4 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/rec.ml: -------------------------------------------------------------------------------- 1 | let x = 1;; 2 | let x = x+1;; 3 | x;; 4 | 5 | let f x = x+1;; 6 | let f x = f (f x);; 7 | f 1;; 8 | 9 | let fact n = if n <=1 then 1 else n*fact(n-1);; 10 | 11 | let rec fact n = if n <=1 then 1 else n*fact(n-1);; 12 | 13 | fact 10;; 14 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/redefinition.ml: -------------------------------------------------------------------------------- 1 | let a = 1;; 2 | 3 | let f x = x + a;; 4 | 5 | f 2;; 6 | 7 | let a = 73;; 8 | 9 | f 2;; 10 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/simultaneous.ml: -------------------------------------------------------------------------------- 1 | let x = 1;; 2 | 3 | (* sequential definitions *) 4 | let x = 2 in 5 | let y = x + 1 in (* y = 2+1 *) 6 | x*y;; (* 2*3 *) 7 | 8 | (* simultaneous definition *) 9 | let x = 2 10 | and y = x+1 in (* y = 1+1 *) 11 | x*y;; (* 2*2 *) 12 | -------------------------------------------------------------------------------- /OCaml_MOOC_W1_ALL/string.ml: -------------------------------------------------------------------------------- 1 | "abc" ^ "def";; 2 | 3 | String.length "12345";; 4 | 5 | int_of_string "12345";; 6 | 7 | string_of_int 12345;; 8 | 9 | String.get "abcdef" 1;; 10 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/Exercise/W2_S1_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | ENIGMA (30/30 points) 3 | Let us solve the following puzzle: 4 | If you multiply my grand-son age by four, you know how old I am. Now, if you exchange the two digits of our ages then you have to multiply by three my age to get the age of my grand-son! 5 | 6 | Write a function exchange of type int -> int that takes an integer x between 10 and 99 and returns an integer which is x whose digits have been exchanged. For instance, exchange 73 = 37. 7 | Define is_valid_answer of type int * int -> bool such that is_valid_answer (grand_father_age, grand_son_age) returns true if and only if grand_father_age and grand_son_age verify the constraints of the puzzle. 8 | Write a function find : (int * int) -> (int * int) that takes a pair (max_grand_father_age, min_grand_son_age) and returns a solution (grand_father_age, grand_son_age) to the problem, where min_grand_son_age <= grand_son_age < grand_father_age <= max_grand_father_age or (-1, -1) if there was no valid answer in the given range. 9 | *) 10 | 11 | let exchange k = 12 | (k mod 10) * 10 + k / 10;; 13 | 14 | let is_valid_answer (grand_father_age, grand_son_age) = 15 | (grand_son_age * 4 = grand_father_age) 16 | && (exchange grand_son_age = 3 * exchange grand_father_age) ;; 17 | 18 | let rec help (grand_father_age, grand_son_age) = 19 | if(grand_father_age<=grand_son_age) 20 | then (-1,-1) 21 | else (if (is_valid_answer (grand_father_age, grand_son_age)) 22 | then (grand_father_age, grand_son_age) 23 | else help (grand_father_age, grand_son_age+1));; 24 | 25 | let rec find answer = 26 | let (a,b)=answer in 27 | if (a <= b) 28 | then (-1,-1) 29 | else (if (help(a,b)=(-1,-1)) 30 | then find (a-1,b) 31 | else help(a,b));; 32 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/Exercise/W2_S2_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | POINTS AND VECTORS (30/30 points) 3 | The given prelude defines three types, one for three dimensional points, another for velocity vectors in three dimensions, and another one representing moving objects in space. 4 | 5 | Write a function move : point -> dpoint -> point such that move p dp is the point p whose coordinates have been updated according to dp. 6 | (x is now x +. dx, y is now y +. dy, z is now z +. dz. 7 | Write a function next : physical_object -> physical_object such that next o is the physical object o at time t + dt. 8 | The position of next o is the position of o moved according to its velocity vector. 9 | Suppose that these objects are spheres whose radius is 1.0. 10 | Write a function will_collide_soon : physical_object -> physical_object -> bool that tells if at the next instant, the two spheres will intersect. 11 | THE GIVEN PRELUDE 12 | 13 | type point = { x : float; y : float; z : float } 14 | type dpoint = { dx : float; dy : float; dz : float } 15 | type physical_object = { position : point; velocity : dpoint } 16 | *) 17 | let move p dp = 18 | {x = p.x +. dp.dx; y= p.y +. dp.dy; z= p.z +. dp.dz};; 19 | 20 | let next obj = 21 | {position = move obj.position obj.velocity; velocity = obj.velocity};; 22 | 23 | let square x = x *. x;; 24 | 25 | let dist (p1:point) (p2:point) = 26 | sqrt (square(p2.x-.p1.x) +. square(p2.y-.p1.y) +. square(p2.z-.p1.z));; 27 | 28 | let will_collide_soon p1 p2 = 29 | dist (next p1).position (next p2).position <= 2.0;; 30 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/Exercise/W2_S2_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | TIME ON PLANET SHADOKUS (30/30 points) 3 | On planet Shadokus, a year has 5 months, each month has 4 days, each day has 3 hours and each hour has 2 minutes. A calendar date is therefore defined as the record type date of the given prelude. 4 | 5 | A date is well-formed if its year index is >= 1, its month index is >= 1 and <= 5, its day index is >= 1 and <= 4, its hour index is >= 0 and <= 2, and its minute index is >= 0 and <= 1. 6 | The start of year 12 would be: 7 | { year = 12; month = 1; day = 1; hour = 0; minute = 0 } 8 | The end of year 12 would be: 9 | { year = 12; month = 5; day = 4; hour = 2; minute = 1 } 10 | 11 | Write a function wellformed : date -> bool which checks that the input date is well formed. 12 | On planet Shadokus, the origin of time is the discovery of the Big-Lambda-Machine, a magical computer that evaluates the infinite lambda-term of time. It is defined by value the_origin_of_time of the given prelude. 13 | Write a function next : date -> date which computes the date which comes one minute after the input date. 14 | In this computer, the time is represented by an integer that counts the number of minutes since 1/1/1 0:0 (the origin of time). 15 | Write a function of_int : int -> date that converts such an integer into a date. 16 | THE GIVEN PRELUDE 17 | 18 | type date = 19 | { year : int; month : int; day : int; 20 | hour : int; minute : int } 21 | 22 | let the_origin_of_time = 23 | { year = 1; month = 1; day = 1; 24 | hour = 0; minute = 0 } 25 | 26 | *) 27 | 28 | let wellformed date = 29 | date.year >= 1 && 30 | date.month >= 1 && date.month <= 5 && 31 | date.day >= 1 && date.day <= 4 && 32 | date.hour >= 0 && date.hour <= 2 && 33 | date.minute >= 0 && date.minute <= 1;; 34 | 35 | let next date = 36 | if date.minute = 0 then 37 | {year = date.year;month=date.month;day=date.day;hour=date.hour;minute=1} 38 | else if date.hour < 2 then 39 | {year = date.year;month=date.month;day=date.day;hour=date.hour+1;minute=the_origin_of_time.minute} 40 | else if date.day < 4 then 41 | {year = date.year;month=date.month;day=date.day+1;hour=the_origin_of_time.hour;minute=the_origin_of_time.minute} 42 | else if date.month < 5 then 43 | {year = date.year;month=date.month+1;day=the_origin_of_time.day;hour=the_origin_of_time.hour;minute=the_origin_of_time.minute} 44 | else 45 | {year = date.year+1;month=the_origin_of_time.month;day=the_origin_of_time.day;hour=the_origin_of_time.hour;minute=the_origin_of_time.minute};; 46 | 47 | let rec help minutes date = 48 | if minutes = 0 49 | then date 50 | else help (minutes-1) (next date);; 51 | 52 | let rec of_int minutes = 53 | help minutes the_origin_of_time;; -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/Exercise/W2_S3_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | FINDING THE MINIMUM (20/20 points) 3 | Consider a non empty array of integers a. 4 | 5 | Write a function min : int array -> int that returns the minimal element of a. 6 | Write a function min_index : int array -> int that returns the index of the minimal element of a. 7 | Do you think these functions work well on large arrays ? 8 | 9 | Define a variable it_scales and set it to "yes" or "no". 10 | *) 11 | let rec help index curr a = 12 | if curr = (Array.length a) - 1 13 | then index 14 | else if a.(curr + 1) < a.(index) 15 | then help (curr + 1) (curr + 1) a 16 | else help index (curr + 1) a;; 17 | 18 | let rec min a = 19 | a.(help 0 0 a);; 20 | 21 | let min_index a = 22 | help 0 0 a;; 23 | 24 | let it_scales = 25 | "no" ;; 26 | 27 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/Exercise/W2_S3_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | SEARCHING FOR STRINGS IN ARRAYS (30/30 points) 3 | Write a function is_sorted : string array -> bool which checks if the values of the input array are sorted in strictly increasing order, implying that its elements are unique (use String.compare). 4 | Using the binary search algorithm, an element can be found very quickly in a sorted array. 5 | Write a function find : string array -> string -> int such that find arr word is the index of the word in the sorted array arr if it occurs in arr or -1 if word does not occur in arr. 6 | The number or array accesses will be counted, to check that you obtain the expected algorithmic complexity. Beware that you really perform the minimal number of accesses. For instance, if your function has to test the contents of a cell twice, be sure to put the result of the access in a variable, and then perform the tests on that variable. 7 | *) 8 | 9 | let rec help1 a cur = 10 | if (a = [||] || cur = (Array.length a) - 1) then true 11 | else if ((String.compare a.(cur + 1) a.(cur)) > 0) then help1 a (cur + 1) 12 | else false 13 | 14 | let is_sorted a = 15 | help1 a 0;; 16 | 17 | let rec help2 l r dict word = 18 | if l > r 19 | then -1 20 | else let m = (l+r)/2 in 21 | let value = dict.(m) in 22 | if String.compare value word < 0 then help2 (m+1) r dict word 23 | else if String.compare value word > 0 then help2 l (m-1) dict word 24 | else m;; 25 | 26 | let find dict word = 27 | help2 0 ((Array.length dict) - 1) dict word;; 28 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/Exercise/W2_S4.ml: -------------------------------------------------------------------------------- 1 | (* 2 | A SMALL TYPED DATABASE (35/35 points) 3 | The code of the mini-database example is given in the prelude. 4 | 5 | You may have noticed that there is an error in the implementation of our database. This error leads to not finding users that should be in the database (because they have been added at some point, and not deleted since) after certain sequences of queries. 6 | Find the bug and give a sequence of operations proof_of_bug of type query array that exhibits it when executed one after the other on an initially empty database. 7 | The failure must be triggered by the last query. 8 | To fix this bug, write a new version of delete that enforces the following invariant on the database, which is expected by the other functions. 9 | All the contacts of a database db (and no others) should be stored in the array db.contacts between indexes 0 and db.number_of_contacts - 1 (inclusive). 10 | Write a new function update : database -> contact -> (bool * database * contact) that either changes the number of an existing person or inserts a new contact. It should return true and the updated database if any of these two options succeeded, or false with the untouched database. The returned contact is not important, it is here just so the function has the same signature as the others. 11 | Write an updated engine function that does an update when given a query with code 3, and uses your updated delete function. 12 | THE GIVEN PRELUDE 13 | 14 | (* A phone number is a sequence of four integers. *) 15 | type phone_number = int * int * int * int;; 16 | 17 | (* A contact has a name and a phone number. *) 18 | type contact = { 19 | name : string; 20 | phone_number : phone_number 21 | };; 22 | 23 | (* Here is a dumb contact. *) 24 | let nobody = { name = ""; phone_number = (0, 0, 0, 0) };; 25 | 26 | (* A database is a collection of contacts. *) 27 | type database = { 28 | number_of_contacts : int; 29 | contacts : contact array; 30 | };; 31 | 32 | (* [make n] is the database with no contact and at most [n] contacts 33 | stored inside. *) 34 | let make max_number_of_contacts = 35 | { 36 | number_of_contacts = 0; 37 | contacts = Array.make max_number_of_contacts nobody 38 | };; 39 | 40 | (* Queries are represented by a code and a contact. 41 | - If the code is 0 then the contact must be inserted. 42 | - If the code is 1 then the contact must be deleted. 43 | - If the code is 2 then we are looking for a contact 44 | with the same name in the database. *) 45 | type query = { 46 | code : int; 47 | contact : contact; 48 | } 49 | 50 | let search db contact = 51 | let rec aux idx = 52 | if idx >= db.number_of_contacts then 53 | (false, db, nobody) 54 | else if db.contacts.(idx).name = contact.name then 55 | (true, db, db.contacts.(idx)) 56 | else 57 | aux (idx + 1) 58 | in 59 | aux 0;; 60 | 61 | let insert db contact = 62 | if db.number_of_contacts >= Array.length db.contacts then 63 | (false, db, nobody) 64 | else 65 | let (status, db, _) = search db contact in 66 | if status then (false, db, contact) else 67 | let cells i = 68 | if i = db.number_of_contacts then contact else db.contacts.(i) 69 | in 70 | let db' = { 71 | number_of_contacts = db.number_of_contacts + 1; 72 | contacts = Array.init (Array.length db.contacts) cells 73 | } 74 | in 75 | (true, db', contact);; 76 | 77 | let delete db contact = 78 | let (status, db, contact) = search db contact in 79 | if not status then (false, db, contact) 80 | else 81 | let cells i = 82 | if db.contacts.(i).name = contact.name then 83 | nobody 84 | else 85 | db.contacts.(i) in 86 | let db' = { 87 | number_of_contacts = db.number_of_contacts - 1; 88 | contacts = Array.init (Array.length db.contacts) cells 89 | } 90 | in 91 | (true, db', contact);; 92 | 93 | (* Engine parses and interprets the query. *) 94 | let engine db { code ; contact } = 95 | if code = 0 then insert db contact 96 | else if code = 1 then delete db contact 97 | else if code = 2 then search db contact 98 | else (false, db, nobody);; 99 | 100 | *) 101 | 102 | let proof_of_bug = 103 | [|{code=0; contact={name="A"; phone_number=(1,2,3,4)}}; 104 | {code=0; contact={name="B"; phone_number=(1,2,3,4)}}; 105 | {code=1; contact={name="A"; phone_number=(1,2,3,4)}}; 106 | {code=2; contact={name="B"; phone_number=(1,2,3,4)}};|];; 107 | 108 | let rec findpos db contact idx = 109 | if (idx >= db.number_of_contacts) 110 | then -1 111 | else if db.contacts.(idx).name = contact.name 112 | then idx 113 | else findpos db contact (1 + idx);; 114 | 115 | let delete db contact = 116 | let (status, db, contact) = search db contact in 117 | if not status then (false, db, contact) 118 | else 119 | let pos = findpos db contact 0 in 120 | let cells i = 121 | if (i = (Array.length db.contacts) - 1) then nobody 122 | else if i < pos then db.contacts.(i) 123 | else db.contacts.(i + 1) in 124 | let db' = { 125 | number_of_contacts = db.number_of_contacts - 1; 126 | contacts = Array.init (Array.length db.contacts) cells 127 | } 128 | in 129 | (true, db', contact);; 130 | 131 | let update db contact = 132 | let (status, db, _) = search db contact in 133 | if status then 134 | let (_,newdb,_) = delete db contact in insert newdb contact 135 | else 136 | insert db contact;; 137 | 138 | let engine db { code ; contact } = 139 | if code = 0 then insert db contact 140 | else if code = 1 then delete db contact 141 | else if code = 2 then search db contact 142 | else if code = 3 then update db contact 143 | else (false, db, nobody);; 144 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/OCaml_MOOC_W2_S0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W2_ALL/OCaml_MOOC_W2_S0.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/OCaml_MOOC_W2_S1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W2_ALL/OCaml_MOOC_W2_S1.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/OCaml_MOOC_W2_S2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W2_ALL/OCaml_MOOC_W2_S2.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/OCaml_MOOC_W2_S3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W2_ALL/OCaml_MOOC_W2_S3.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/OCaml_MOOC_W2_S4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W2_ALL/OCaml_MOOC_W2_S4.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/W1Hello.srt: -------------------------------------------------------------------------------- 1 | 1 2 | 00:00:02,960 --> 00:00:07,430 3 | Welcome, we are OCamlPro, 4 | the leading company in OCaml development. 5 | 6 | 2 7 | 00:00:07,430 --> 00:00:09,520 8 | We are very proud and excited, 9 | 10 | 3 11 | 00:00:09,520 --> 00:00:12,260 12 | to be part of the design team of this MOOC. 13 | 14 | 4 15 | 00:00:12,260 --> 00:00:15,040 16 | At OCamlPro, we all come 17 | from the research world. 18 | 19 | 5 20 | 00:00:15,040 --> 00:00:18,000 21 | We participate in several R&D projects, 22 | 23 | 6 24 | 00:00:18,000 --> 00:00:20,520 25 | with industrial and academic partners. 26 | 27 | 7 28 | 00:00:20,520 --> 00:00:22,939 29 | And we edit software 30 | at the state of the art 31 | 32 | 8 33 | 00:00:22,939 --> 00:00:24,220 34 | of academic research. 35 | 36 | 9 37 | 00:00:24,220 --> 00:00:27,369 38 | We designed the platform that 39 | you will use for you exercises. 40 | 41 | 10 42 | 00:00:27,369 --> 00:00:30,090 43 | It features a code editor 44 | that checks your syntax, 45 | 46 | 11 47 | 00:00:30,090 --> 00:00:31,160 48 | points out your errors, 49 | 50 | 12 51 | 00:00:31,160 --> 00:00:33,110 52 | and automatically formats your code. 53 | 54 | 13 55 | 00:00:33,110 --> 00:00:34,710 56 | You can try your code on the fly 57 | 58 | 14 59 | 00:00:34,710 --> 00:00:37,160 60 | in the interactive OCaml interpreter. 61 | 62 | 15 63 | 00:00:37,160 --> 00:00:38,350 64 | Nothing needs to be installed 65 | 66 | 16 67 | 00:00:38,350 --> 00:00:40,230 68 | to enjoy learning OCaml. 69 | 70 | 17 71 | 00:00:40,230 --> 00:00:42,000 72 | Enjoy, as much as we did! 73 | 74 | 18 75 | 00:00:44,000 --> 00:00:45,410 76 | My name is Fabrice Le Fessant, 77 | 78 | 19 79 | 00:00:45,410 --> 00:00:46,750 80 | I am a researcher at INRIA, 81 | 82 | 20 83 | 00:00:46,750 --> 00:00:50,679 84 | I've been working with OCaml 85 | for the last twenty years. 86 | 87 | 21 88 | 00:00:50,679 --> 00:00:53,829 89 | I decided at some point to create 90 | the OCamlPro company. 91 | 92 | 22 93 | 00:00:53,829 --> 00:00:54,879 94 | I'm Mohamed, 95 | 96 | 23 97 | 00:00:54,879 --> 00:00:59,359 98 | At OCamlPro, I'm working on a software 99 | that is called AltErgo, 100 | 101 | 24 102 | 00:00:59,359 --> 00:01:01,989 103 | that takes as input mathematical formulas, 104 | 105 | 25 106 | 00:01:01,989 --> 00:01:06,950 107 | and tries to prove 108 | whether they are valid or not. 109 | 110 | 26 111 | 00:01:06,950 --> 00:01:07,299 112 | I am Thomas, 113 | 114 | 27 115 | 00:01:07,299 --> 00:01:09,829 116 | I work at OCamlPro as a PhD student, 117 | 118 | 28 119 | 00:01:09,829 --> 00:01:14,049 120 | the purpose of my job is to evaluate the potenial 121 | 122 | 29 123 | 00:01:14,049 --> 00:01:18,280 124 | uncaught exception of an OCaml program. 125 | 126 | 30 127 | 00:01:18,280 --> 00:01:19,960 128 | I'm Louis Gesbert, 129 | 130 | 31 131 | 00:01:19,960 --> 00:01:24,210 132 | my main project is the OCamlPachage Manager 133 | (OPAM), 134 | 135 | 32 136 | 00:01:24,210 --> 00:01:26,880 137 | which is probably the first thing 138 | you will install, 139 | 140 | 33 141 | 00:01:26,880 --> 00:01:29,869 142 | if you want to try OCaml on your own. 143 | 144 | 34 145 | 00:01:29,869 --> 00:01:30,810 146 | My name is Pierrick, 147 | 148 | 35 149 | 00:01:30,810 --> 00:01:34,369 150 | and I'm a PhD student at OCamlPro. 151 | 152 | 36 153 | 00:01:34,369 --> 00:01:37,079 154 | My job is to improve the safety 155 | 156 | 37 157 | 00:01:37,079 --> 00:01:39,930 158 | and the correctness of the OCaml compiler. 159 | 160 | 38 161 | 00:01:39,930 --> 00:01:45,250 162 | Yes! It's a lot of fun to work 163 | with the OCamlPro engineers! 164 | 165 | 39 166 | 00:01:45,250 --> 00:01:47,430 167 | They are all working on different subjects, 168 | 169 | 40 170 | 00:01:47,430 --> 00:01:48,680 171 | state of the art research, 172 | 173 | 41 174 | 00:01:48,680 --> 00:01:50,899 175 | different application domains. 176 | 177 | 42 178 | 00:01:50,899 --> 00:01:54,000 179 | It's a lot of fun to work with OCaml. 180 | 181 | 43 182 | 00:01:54,000 --> 00:02:00,229 183 | The language is cool, plus, you always get 184 | to work on interesting problems 185 | 186 | 44 187 | 00:02:00,229 --> 00:02:02,450 188 | when you work on OCaml. 189 | 190 | 45 191 | 00:02:02,450 --> 00:02:05,770 192 | I think OCaml is a really cool language, 193 | 194 | 46 195 | 00:02:05,770 --> 00:02:09,840 196 | what I like about it is 197 | especially the pattern matching, 198 | 199 | 47 200 | 00:02:09,840 --> 00:02:14,010 201 | which solves many, many problems. 202 | 203 | 48 204 | 00:02:14,010 --> 00:02:15,330 205 | And the type system. 206 | 207 | 49 208 | 00:02:15,330 --> 00:02:19,290 209 | Even if it is sometimes a bit annoying 210 | to write a program, 211 | 212 | 50 213 | 00:02:19,290 --> 00:02:23,690 214 | because the compiler says: 215 | "Oh no! you can't do that!" 216 | 217 | 51 218 | 00:02:23,690 --> 00:02:25,090 219 | But... he is always right! 220 | 221 | 52 222 | 00:02:25,090 --> 00:02:27,730 223 | I really like OCaml because i know that 224 | 225 | 53 226 | 00:02:27,730 --> 00:02:29,590 227 | when I program in OCaml, 228 | 229 | 54 230 | 00:02:29,590 --> 00:02:34,260 231 | there is a range of errors 232 | that I will not have in my code 233 | 234 | 55 235 | 00:02:34,260 --> 00:02:38,260 236 | such as null pointer exceptions 237 | or implicit type casts. 238 | 239 | 56 240 | 00:02:38,260 --> 00:02:41,510 241 | I think I would be sad 242 | if had to switch to another language. 243 | 244 | 57 245 | 00:02:41,510 --> 00:02:45,800 246 | I really like programming in OCaml everyday. 247 | 248 | 58 249 | 00:02:45,800 --> 00:02:53,300 250 | Welcome to OCaml! 251 | 252 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/W1Hello_fr.srt: -------------------------------------------------------------------------------- 1 | 1 2 | 00:00:02,960 --> 00:00:07,430 3 | Bienvenue, nous sommes OCamlPro, 4 | la société leader dans le développement OCaml. 5 | 6 | 2 7 | 00:00:07,430 --> 00:00:09,520 8 | Nous sommes très fiers et enthousiastes, 9 | 10 | 3 11 | 00:00:09,520 --> 00:00:12,260 12 | de faire partie de l'équipe de conception de ce MOOC. 13 | 14 | 4 15 | 00:00:12,260 --> 00:00:15,040 16 | Au OCamlPro, nous venons tous 17 | du monde de la recherche. 18 | 19 | 5 20 | 00:00:15,040 --> 00:00:18,000 21 | Nous participons à plusieurs projets de R&D, 22 | 23 | 6 24 | 00:00:18,000 --> 00:00:20,520 25 | avec des partenaires industriels et académiques. 26 | 27 | 7 28 | 00:00:20,520 --> 00:00:22,939 29 | Et nous éditons des logiciels 30 | suivant l'état de l'art 31 | 32 | 8 33 | 00:00:22,939 --> 00:00:24,220 34 | de la recherche universitaire. 35 | 36 | 9 37 | 00:00:24,220 --> 00:00:27,369 38 | Nous avons conçu la plate-forme que 39 | vous allez utiliser pour les exercices. 40 | 41 | 10 42 | 00:00:27,369 --> 00:00:30,090 43 | Elle dispose d'un éditeur de code 44 | qui vérifie votre syntaxe, 45 | 46 | 11 47 | 00:00:30,090 --> 00:00:31,160 48 | souligne vos erreurs, 49 | 50 | 12 51 | 00:00:31,160 --> 00:00:33,110 52 | et indente automatiquement votre code. 53 | 54 | 13 55 | 00:00:33,110 --> 00:00:34,710 56 | Vous pouvez essayer votre code à la volée 57 | 58 | 14 59 | 00:00:34,710 --> 00:00:37,160 60 | dans le toplevel OCaml embarqué. 61 | 62 | 15 63 | 00:00:37,160 --> 00:00:38,350 64 | Vous n'avez rien à installer 65 | 66 | 16 67 | 00:00:38,350 --> 00:00:40,230 68 | pour vous amusez en apprenant OCaml. 69 | 70 | 17 71 | 00:00:40,230 --> 00:00:42,000 72 | Nous vous souhaitons autant de plaisir 73 | que nous en avions eu en apprenant OCaml. 74 | 75 | 18 76 | 00:00:44,000 --> 00:00:45,410 77 | Mon nom est Fabrice Le Fessant, 78 | 79 | 19 80 | 00:00:45,410 --> 00:00:46,750 81 | Je suis un chercheur à l'INRIA, 82 | 83 | 20 84 | 00:00:46,750 --> 00:00:50,679 85 | Je travaille avec OCaml depuis plus de vingt ans. 86 | 87 | 21 88 | 00:00:50,679 --> 00:00:53,829 89 | Un jour, j'ai décidé de créer la société OCamlPro. 90 | 91 | 22 92 | 00:00:53,829 --> 00:00:54,879 93 | Je suis Mohamed, 94 | 95 | 23 96 | 00:00:54,879 --> 00:00:59,359 97 | Pour OCamlPro, je travaille 98 | sur un logiciel que l'on appelle AltErgo, 99 | 100 | 24 101 | 00:00:59,359 --> 00:01:01,989 102 | qui prend en entrée des formules mathématiques, 103 | 104 | 25 105 | 00:01:01,989 --> 00:01:06,950 106 | et tente de prouver si elles sont valides ou non. 107 | 108 | 26 109 | 00:01:06,950 --> 00:01:07,299 110 | Je suis Thomas. 111 | 112 | 27 113 | 00:01:07,299 --> 00:01:09,829 114 | Je travaille comme doctorant chez OCamlPro. 115 | 116 | 28 117 | 00:01:09,829 --> 00:01:14,049 118 | Le but de mon travail est de détecter 119 | 120 | 29 121 | 00:01:14,049 --> 00:01:18,280 122 | les éventuelles exceptions non rattrapées 123 | d'un programme OCaml. 124 | 125 | 30 126 | 00:01:18,280 --> 00:01:19,960 127 | Je suis Louis Gesbert. 128 | 129 | 31 130 | 00:01:19,960 --> 00:01:24,210 131 | Mon principal projet est 132 | le gestionnaire paquet OPAM, 133 | 134 | 32 135 | 00:01:24,210 --> 00:01:26,880 136 | qui est probablement la première chose 137 | vous installerez 138 | 139 | 33 140 | 00:01:26,880 --> 00:01:29,869 141 | si vous voulez continuer avec OCaml. 142 | 143 | 34 144 | 00:01:29,869 --> 00:01:30,810 145 | Mon nom est Pierrick, 146 | 147 | 35 148 | 00:01:30,810 --> 00:01:34,369 149 | et je suis doctorant chez OCamlPro. 150 | 151 | 36 152 | 00:01:34,369 --> 00:01:37,079 153 | Mon travail consiste à améliorer la sécurité 154 | 155 | 37 156 | 00:01:37,079 --> 00:01:39,930 157 | et l'exactitude du compilateur OCaml. 158 | 159 | 38 160 | 00:01:39,930 --> 00:01:45,250 161 | Oui! Il y a beaucoup de plaisir à travailler 162 | avec les ingénieurs OCamlPro! 163 | 164 | 39 165 | 00:01:45,250 --> 00:01:47,430 166 | Ils travaillent tous sur différents sujets, 167 | 168 | 40 169 | 00:01:47,430 --> 00:01:48,680 170 | à la pointe de la recherche, 171 | 172 | 41 173 | 00:01:48,680 --> 00:01:50,899 174 | dans différents domaines d'application. 175 | 176 | 42 177 | 00:01:50,899 --> 00:01:54,000 178 | Il y a beaucoup de plaisir à travailler avec OCaml. 179 | 180 | 43 181 | 00:01:54,000 --> 00:02:00,229 182 | La langue est cool, et en prime, vous travaillez 183 | toujours sur les problèmes intéressants 184 | 185 | 44 186 | 00:02:00,229 --> 00:02:02,450 187 | lorsque vous travaillez sur OCaml. 188 | 189 | 45 190 | 00:02:02,450 --> 00:02:05,770 191 | Je pense que OCaml est un langage vraiment cool. 192 | 193 | 46 194 | 00:02:05,770 --> 00:02:09,840 195 | Ce qui me plaît en particulier, 196 | c'est le filtrage de motif, 197 | 198 | 47 199 | 00:02:09,840 --> 00:02:14,010 200 | qui résout beaucoup, beaucoup de problèmes. 201 | 202 | 48 203 | 00:02:14,010 --> 00:02:15,330 204 | Et le système de type. 205 | 206 | 49 207 | 00:02:15,330 --> 00:02:19,290 208 | Même s'il est parfois un peu contraignant 209 | 210 | 50 211 | 00:02:19,290 --> 00:02:23,690 212 | ---parce que le compilateur dit: 213 | « Oh non ! Vous ne pouvez pas faire ça ! »--- 214 | 215 | 51 216 | 00:02:23,690 --> 00:02:25,090 217 | Mais... il a toujours raison! 218 | 219 | 52 220 | 00:02:25,090 --> 00:02:27,730 221 | Je aime vraiment OCaml, 222 | 223 | 53 224 | 00:02:27,730 --> 00:02:29,590 225 | parce que je sais que quand je programme en OCaml, 226 | 227 | 54 228 | 00:02:29,590 --> 00:02:34,260 229 | il existe une gamme d'erreurs 230 | que je ne vais pas avoir dans mon code. 231 | 232 | 55 233 | 00:02:34,260 --> 00:02:38,260 234 | Comme les exceptions de pointeur NULL 235 | ou les conversions implicites de type. 236 | 237 | 56 238 | 00:02:38,260 --> 00:02:41,510 239 | Je pense que je serais triste 240 | si je dois passer à un autre langage. 241 | 242 | 57 243 | 00:02:41,510 --> 00:02:45,800 244 | Je aime vraiment programmer en OCaml chaque jour. 245 | 246 | 58 247 | 00:02:45,800 --> 00:02:53,300 248 | Bienvenue à OCaml! -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/W1Hello_pt.srt: -------------------------------------------------------------------------------- 1 | 1 2 | 00:00:02,960 --> 00:00:07,430 3 | Bem-vindos, somos OCamlPro, 4 | a empresa líder no desenvolvimento OCaml. 5 | 6 | 2 7 | 00:00:07,430 --> 00:00:09,520 8 | É com orgulho e muito entusiamo, 9 | 10 | 3 11 | 00:00:09,520 --> 00:00:12,260 12 | que participamos na equipa que concebe este MOOC. 13 | 14 | 4 15 | 00:00:12,260 --> 00:00:15,040 16 | Na OCamlPro, viemos todos do mundo 17 | da investigação. 18 | 19 | 5 20 | 00:00:15,040 --> 00:00:18,000 21 | Participámos em vários projetos de 22 | investigação e desenvolvimento, 23 | 24 | 6 25 | 00:00:18,000 --> 00:00:20,520 26 | com parceiros industriais e académicos. 27 | 28 | 7 29 | 00:00:20,520 --> 00:00:22,939 30 | E editamos software no estado da arte 31 | 32 | 8 33 | 00:00:22,939 --> 00:00:24,220 34 | da investigação académica. 35 | 36 | 9 37 | 00:00:24,220 --> 00:00:27,369 38 | concebemos a plataforma que vai utilizar para os exercícios. 39 | 40 | 10 41 | 00:00:27,369 --> 00:00:30,090 42 | Esta disponibiliza um editor de código que verifica 43 | a vossa sintaxe, 44 | 45 | 11 46 | 00:00:30,090 --> 00:00:31,160 47 | assinala os vossos erros, 48 | 49 | 12 50 | 00:00:31,160 --> 00:00:33,110 51 | e indenta automaticamente o vosso código. 52 | 53 | 13 54 | 00:00:33,110 --> 00:00:34,710 55 | Pode experimentar o seu código << on-the-fly >> 56 | 57 | 14 58 | 00:00:34,710 --> 00:00:37,160 59 | no toplevel OCaml embutido. 60 | 61 | 15 62 | 00:00:37,160 --> 00:00:38,350 63 | Não precisa de instalar nada 64 | 65 | 16 66 | 00:00:38,350 --> 00:00:40,230 67 | para brincar enquanto aprende OCaml. 68 | 69 | 17 70 | 00:00:40,230 --> 00:00:42,000 71 | Desejamo-vos tanto prazer na vossa aprendizagem de 72 | OCaml quanto nós tivemos. 73 | 74 | 18 75 | 00:00:44,000 --> 00:00:45,410 76 | Meu nome é Fabrice Le Fessant, 77 | 78 | 19 79 | 00:00:45,410 --> 00:00:46,750 80 | Sou investigador no INRIA, 81 | 82 | 20 83 | 00:00:46,750 --> 00:00:50,679 84 | trabalho com OCaml há mais de vinte anos. 85 | 86 | 21 87 | 00:00:50,679 --> 00:00:53,829 88 | Um dia decidi criar a empresa OCamlPro. 89 | 90 | 22 91 | 00:00:53,829 --> 00:00:54,879 92 | Eu sou Mohamed, 93 | 94 | 23 95 | 00:00:54,879 --> 00:00:59,359 96 | na OCamlPro, trabalho num software 97 | que se chama AltErgo, 98 | 99 | 24 100 | 00:00:59,359 --> 00:01:01,989 101 | que toma em entrada fórmulas matemáticas, 102 | 103 | 25 104 | 00:01:01,989 --> 00:01:06,950 105 | e tenta demonstrar se estas são válidas ou não. 106 | 107 | 26 108 | 00:01:06,950 --> 00:01:07,299 109 | Eu sou Thomas. 110 | 111 | 27 112 | 00:01:07,299 --> 00:01:09,829 113 | Sou aluno de doutoramento na OCamlPro. 114 | 115 | 28 116 | 00:01:09,829 --> 00:01:14,049 117 | O objectivo do meu trabalho é detetar 118 | 119 | 29 120 | 00:01:14,049 --> 00:01:18,280 121 | as eventuais excepções não processadas num programa OCaml. 122 | 123 | 30 124 | 00:01:18,280 --> 00:01:19,960 125 | Eu sou Louis Gesbert. 126 | 127 | 31 128 | 00:01:19,960 --> 00:01:24,210 129 | O meu principal projeto é o 130 | gestor de pacote OPAM, 131 | 132 | 32 133 | 00:01:24,210 --> 00:01:26,880 134 | que é provavelmente a primeira coisa que instalará 135 | 136 | 33 137 | 00:01:26,880 --> 00:01:29,869 138 | se quer continuar com OCaml. 139 | 140 | 34 141 | 00:01:29,869 --> 00:01:30,810 142 | Meu nome é Pierrick, 143 | 144 | 35 145 | 00:01:30,810 --> 00:01:34,369 146 | e sou aluno de doutoramento na OCamlPro. 147 | 148 | 36 149 | 00:01:34,369 --> 00:01:37,079 150 | O meu trabalho é melhorar a segurança 151 | 152 | 37 153 | 00:01:37,079 --> 00:01:39,930 154 | e a precisão do compilador OCaml. 155 | 156 | 38 157 | 00:01:39,930 --> 00:01:45,250 158 | Sim! É muito agradável trabalhar 159 | com os engenheiros OCamlPro! 160 | 161 | 39 162 | 00:01:45,250 --> 00:01:47,430 163 | Trabalham todos em temas variados e diferentes, 164 | 165 | 40 166 | 00:01:47,430 --> 00:01:48,680 167 | na ponta da investigação, 168 | 169 | 41 170 | 00:01:48,680 --> 00:01:50,899 171 | em diferentes domínios de aplicações. 172 | 173 | 42 174 | 00:01:50,899 --> 00:01:54,000 175 | É muito agradável trabalhar com OCaml. 176 | 177 | 43 178 | 00:01:54,000 --> 00:02:00,229 179 | A linguagem é fixe, e ainda por cima, trabalhamos 180 | sempre com problemas interessantes 181 | 182 | 44 183 | 00:02:00,229 --> 00:02:02,450 184 | quando trabalhamos com OCaml. 185 | 186 | 45 187 | 00:02:02,450 --> 00:02:05,770 188 | Penso que OCaml é realmente uma linguagem simpática. 189 | 190 | 46 191 | 00:02:05,770 --> 00:02:09,840 192 | O que me agrada em particular é o filtro, 193 | 194 | 47 195 | 00:02:09,840 --> 00:02:14,010 196 | que resolve muitos, mesmo muitos problemas. 197 | 198 | 48 199 | 00:02:14,010 --> 00:02:15,330 200 | E o sistema de tipos. 201 | 202 | 49 203 | 00:02:15,330 --> 00:02:19,290 204 | Mesmo que pareça, por vezes, constrangedor 205 | 206 | 50 207 | 00:02:19,290 --> 00:02:23,690 208 | ---porque o compilador diz: 209 | « Não Não! Não pode fazer isso! »--- 210 | 211 | 51 212 | 00:02:23,690 --> 00:02:25,090 213 | Mas... ele tem sempre razão! 214 | 215 | 52 216 | 00:02:25,090 --> 00:02:27,730 217 | Aprecio mesmo o OCaml, 218 | 219 | 53 220 | 00:02:27,730 --> 00:02:29,590 221 | porque sei que quando programo em OCaml, 222 | 223 | 54 224 | 00:02:29,590 --> 00:02:34,260 225 | existe um conjunto de erros que 226 | não terei no meu código. 227 | 228 | 55 229 | 00:02:34,260 --> 00:02:38,260 230 | Como as excepções de apontador NULL 231 | ou de conversão implícitas de tipos. 232 | 233 | 56 234 | 00:02:38,260 --> 00:02:41,510 235 | Penso que ficarei triste se tiver 236 | de mudar de linguagem. 237 | 238 | 57 239 | 00:02:41,510 --> 00:02:45,800 240 | Eu gosto mesmo muito de programar OCaml diariamente. 241 | 242 | 58 243 | 00:02:45,800 --> 00:02:53,300 244 | Bem-vindos ao OCaml! 245 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/ambiguousField.ml: -------------------------------------------------------------------------------- 1 | type a = { x : int; b : int; };; 2 | type b = { y : int; c : int; };; 3 | { x = 0; b = 2 };; 4 | type t = { x : bool };; 5 | type u = { x : int };; 6 | { x = true };; 7 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/colors.ml: -------------------------------------------------------------------------------- 1 | type color = int;; 2 | let red : color = 0;; 3 | let white : color = 1;; 4 | let blue : color = 2;; 5 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/db.ml: -------------------------------------------------------------------------------- 1 | (* A phone number is a sequence of four integers. *) 2 | type phone_number = int * int * int * int;; 3 | (* break *) 4 | (* A contact has a name and a phone number. *) 5 | type contact = { 6 | name : string; 7 | phone_number : phone_number 8 | };; 9 | (* Here is a dumb contact. *) 10 | let nobody = { name = ""; phone_number = (0, 0, 0, 0) };; 11 | (* break *) 12 | (* A database is a collection of contacts. *) 13 | type database = { 14 | number_of_contacts : int; 15 | contacts : contact array; 16 | };; 17 | (* break *) 18 | (* [make n] is the database with no contact and at most [n] contacts 19 | stored inside. *) 20 | let make max_number_of_contacts = 21 | { 22 | number_of_contacts = 0; 23 | contacts = Array.make max_number_of_contacts nobody 24 | };; 25 | (* break *) 26 | (* Queries are represented by a code and a contact. 27 | - If the code is 0 then the contact must be inserted. 28 | - If the code is 1 then the contact must be deleted. 29 | - If the code is 2 then we are looking for a contact with the same name in the database. 30 | *) 31 | type query = { 32 | code : int; 33 | contact : contact; 34 | } 35 | (* break *) 36 | let search db contact = 37 | let rec aux idx = 38 | if idx >= db.number_of_contacts then 39 | (false, db, nobody) 40 | else if db.contacts.(idx).name = contact.name then 41 | (true, db, db.contacts.(idx)) 42 | else 43 | aux (idx + 1) 44 | in 45 | aux 0;; 46 | (* break *) 47 | let insert db contact = 48 | if db.number_of_contacts >= Array.length db.contacts then 49 | (false, db, nobody) 50 | else 51 | let (status, db, _) = search db contact in 52 | if status then (false, db, contact) else 53 | let cells i = 54 | if i = db.number_of_contacts then contact else db.contacts.(i) 55 | in 56 | let db' = { 57 | number_of_contacts = db.number_of_contacts + 1; 58 | contacts = Array.init (Array.length db.contacts) cells 59 | } 60 | in 61 | (true, db', contact);; 62 | (* break *) 63 | let delete db contact = 64 | let (status, db, contact) = search db contact in 65 | if not status then (false, db, contact) 66 | else 67 | let cells i = if db.contacts.(i).name = contact.name then nobody else db.contacts.(i) in 68 | let db' = { 69 | number_of_contacts = db.number_of_contacts - 1; 70 | contacts = Array.init (Array.length db.contacts) cells 71 | } 72 | in 73 | (true, db', contact);; 74 | (* break *) 75 | (* Engine parses and interprets the query. *) 76 | let engine db (code, contact) = 77 | if code = 0 then insert db contact 78 | else if code = 1 then delete db contact 79 | else if code = 2 then search db contact 80 | else (false, db, nobody);; 81 | (* break *) 82 | let db = make 5;; 83 | let (status, db, contact) = engine db (0, { name = "luke"; phone_number = (1, 2, 3, 4) });; 84 | let (status, db, contact) = engine db (0, { name = "darth"; phone_number = (4, 3, 2, 1) });; 85 | let (status, db, contact) = engine db (2, { name = "luke"; phone_number = (1, 2, 3, 4) });; 86 | let (status, db, contact) = engine db (1, { name = "luke"; phone_number = (4, 3, 2, 1) });; 87 | let (status, db, contact) = engine db (2, { name = "luke"; phone_number = (1, 2, 3, 4) });; 88 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/equality.ml: -------------------------------------------------------------------------------- 1 | let x = (1, 2);; 2 | let y = (1, 2);; 3 | let z = x;; 4 | let x_is_structural_equal_to_y = (x = y);; 5 | let x_is_not_physically_equal_to_y = (x == y);; 6 | let x_is_physically_equal_to_z = (x == z);; 7 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/extractCoordinates.ml: -------------------------------------------------------------------------------- 1 | let a = (3 * 6, 4 * 6);; 2 | let (x, _) = a;; 3 | let abscissa (x, _) = x;; 4 | let ordinate (_, y) = y;; 5 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/heterogeneous.ml: -------------------------------------------------------------------------------- 1 | let a = [| true; 1 |];; 2 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/illtypedField.ml: -------------------------------------------------------------------------------- 1 | type person = { name : string ; age : int };; 2 | let luke = { name = "Skywalker"; age = "26" };; 3 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/invalidExtract.ml: -------------------------------------------------------------------------------- 1 | let abscissa (x, y) = y;; 2 | let ordinate (x, y) = x;; 3 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/invalidPattern.ml: -------------------------------------------------------------------------------- 1 | let (x, _) = (1, 2, 3);; 2 | let (x, x, y) = (1, 2, 3);; 3 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/literal.ml: -------------------------------------------------------------------------------- 1 | let p = [| 1; 2; 3 |];; 2 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/missingField.ml: -------------------------------------------------------------------------------- 1 | type point2D = { x : int; y : int };; 2 | let oups = { x = 0 };; 3 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/multipleTypeDefinition.ml: -------------------------------------------------------------------------------- 1 | type t = int;; 2 | let x : t = 0;; 3 | type t = bool;; 4 | let f (x : t) = not x;; 5 | let z = f x;; 6 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/outofbound.ml: -------------------------------------------------------------------------------- 1 | let a = [| 0; 1; 2 |];; 2 | let x = a.(3);; 3 | let y = a.(-1);; 4 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/predicate.ml: -------------------------------------------------------------------------------- 1 | (** A property over integers is represented as a function 2 | from integers to booleans. *) 3 | type int_property = int -> bool;; 4 | 5 | (** Similarly, a function from strings to booleans is a 6 | good representation for a property over strings. *) 7 | type string_property = string -> bool;; 8 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/seq.ml: -------------------------------------------------------------------------------- 1 | let square x = x * x;; 2 | let squares n = Array.init n square;; 3 | let s1 = squares 5;; 4 | let a1 = s1.(4) 5 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/set.ml: -------------------------------------------------------------------------------- 1 | (** Sets of integers can be represented using a function. 2 | (Yet, this is a very inefficient representation.) 3 | *) 4 | type set = int -> bool;; 5 | 6 | let empty : set = 7 | fun x -> false;; 8 | 9 | let add (x : int) (s : set) : set = 10 | fun y -> (x = y) || s y;; 11 | 12 | let mem (x : int) (s : set) : bool = 13 | s x;; 14 | 15 | let s = add 1 (add 3 empty);; 16 | 17 | let one_is_in_s = mem 1 s;; 18 | let two_is_not_in_s = mem 2 s;; 19 | let three_is_in_s = mem 3 s;; 20 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/smallCoordinates.ml: -------------------------------------------------------------------------------- 1 | let origin = (0, 0);; 2 | let x_positive_limit = (max_int, 0);; 3 | let x_negative_limit = (min_int, 0);; 4 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/smallCoordinates2.ml: -------------------------------------------------------------------------------- 1 | type point2D = { x : int; y : int };; 2 | let origin = { x = 0; y = 0 };; 3 | let from_tuple (x, y) = { x; y };; 4 | let a : point2D = from_tuple (4, 2);; 5 | let b : point2D = from_tuple (10, 5);; 6 | type box = { 7 | left_upper_corner : point2D; 8 | right_lower_corner : point2D; 9 | };; 10 | let the_box = { left_upper_corner = a; right_lower_corner = b };; 11 | let get_min_x { left_upper_corner = { x } } = x;; 12 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/smallCoordinatesWithTypeAnnotations.ml: -------------------------------------------------------------------------------- 1 | type point2D = int * int;; 2 | let origin : point2D = (0, 0);; 3 | let x_positive_limit : point2D = (max_int, 0);; 4 | let x_negative_limit : point2D = (min_int, 0);; 5 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/stdSwap.ml: -------------------------------------------------------------------------------- 1 | let swap a = [| a.(1); a.(0) |];; 2 | let b = swap [| 0; 1 |];; 3 | let c = swap [| 0; 1; 2 |];; 4 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/swap.ml: -------------------------------------------------------------------------------- 1 | let swap [| x; y |] = [| y; x |];; 2 | let t = swap [| 2; 1 |];; 3 | let t = swap [| 2; 1; 0 |];; 4 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/typeAnnotations.ml: -------------------------------------------------------------------------------- 1 | type positive = int;; 2 | let abs (x : int) = (if x < 0 then -x else x : positive);; 3 | let abs' (x : int) : positive = if x < 0 then -x else x;; 4 | -------------------------------------------------------------------------------- /OCaml_MOOC_W2_ALL/typofield.ml: -------------------------------------------------------------------------------- 1 | type point2D = { x : int; y : int };; 2 | let p = { x = 42; z = 3 };; 3 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/Exercise/W3_S0_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | PATTERN MATCHING EXHAUSTIVITY (10/10 points) 3 | We have seen in the course the example of non exhaustive pattern matching given below. Write the code for the missing cases. 4 | 5 | THE GIVEN PRELUDE 6 | 7 | type color = Black | Gray | White ;; 8 | *) 9 | let lighter c1 c2 = 10 | match (c1, c2) with 11 | | (Black, Black) -> false 12 | | (White, White) -> false 13 | | (Gray, Gray) -> false 14 | | (Black, _) -> true 15 | | (_, White) -> true 16 | | (White, _) -> false 17 | | (_, Black) -> false 18 | ;; 19 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/Exercise/W3_S0_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | A TYPE FOR ARRAY INDEXES (40/40 points) 3 | The previous week, we asked you the following question: Consider a non empty array of integers a, write a function min_index : int array -> int that returns the index of the minimal element of a. 4 | As the arrays contain integers and the indices of arrays are also represented by integers, you might have confused an index and the content of a cell. To avoid such a confusion, let us define a type for index (given in the prelude below). 5 | This type has a single constructor waiting for one integer. 6 | For instance, if you want to represent the index 0, use the value Index 0. 7 | Defining such a type is interesting because it allows the type-checker to check that an integer is not used where an index is expected (or the converse). 8 | 9 | Write a function read : int array -> index -> int such that read a (Index k) returns the k-th element of a. 10 | Write a function inside : int array -> index -> bool such that inside a idx is true if and only if idx is a valid index for the array a. 11 | Write a function next : index -> index such that next (Index k) is equal to Index (k + 1). 12 | Consider a non empty array of integers a, write a function min_index : int array -> index that returns the index of the minimal element of a. 13 | THE GIVEN PRELUDE 14 | 15 | type index = Index of int 16 | *) 17 | let read a index = 18 | match index with 19 | | Index i -> a.(i);; 20 | 21 | let inside a index = 22 | match index with 23 | | Index i -> i >= 0 && i < Array.length a;; 24 | 25 | let next index = 26 | match index with 27 | | Index i -> Index (i+1);; 28 | 29 | let min_index a = 30 | let rec help a mindex index = 31 | if not (inside a index) 32 | then mindex 33 | else 34 | if (read a mindex) > (read a index) 35 | then help a index (next index) 36 | else help a mindex (next index) 37 | in 38 | help a (Index 0) (Index 1);; 39 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/Exercise/W3_S0_3.ml: -------------------------------------------------------------------------------- 1 | (* 2 | THE OPTION TYPE (30/30 points) 3 | Optional values are commonly used in OCaml in the return type of partial functions, i.e. functions that may fail on some input. The following questions illustrate such situations. 4 | In the Pervasives module which is loaded automatically, there is a type option with two constructors: 5 | Some (e) has type 't option if e has type 't and represents the presence of some value e of type 't. 6 | None has type 't option and represents the absence of some value of type 't. 7 | 8 | Write a function find : string array -> string -> int option such that find a w = Some idx if a.(idx) = w and find a w = None if there is no such index. 9 | Sometimes, when a value of type t is missing, a default value should be used. 10 | Write a function default_int : int option -> int such that: default_int None = 0 and default_int (Some x) = x. 11 | Write a function merge : int option -> int option -> int option such that: 12 | merge None None = None 13 | merge (Some x) None = merge None (Some x) = Some x 14 | merge (Some x) (Some y) = Some (x + y) 15 | *) 16 | let find a w = 17 | let rec help pos = 18 | if (a.(pos) = w) then Some pos 19 | else if (pos = (Array.length a) - 1) then None 20 | else help (pos+1) 21 | in 22 | if(a = [||]) then None 23 | else help 0;; 24 | 25 | let default_int = 26 | function 27 | | None -> 0 28 | | Some x -> x;; 29 | 30 | let merge a b = 31 | match (a, b) with 32 | | (None, None) -> None 33 | | (Some x, Some y) -> Some (x+y) 34 | | (Some x, None) -> Some x 35 | | (None, Some y) -> Some y;; -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/Exercise/W3_S1_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | FIRST IN FIRST OUT (50/50 points) 3 | A queue is a standard FIFO data structure. See wikipedia 4 | 5 | In this exercise, we implement a queue with a pair of two lists (front, back) such that front @ List.rev back represents the sequence of elements in the queue. 6 | 7 | Write a function is_empty : queue -> bool such that is_empty q is true if and only if q has no element. 8 | Write a function enqueue : int -> queue -> queue such that enqueue x q is the queue as q except that x is at the end of the queue. 9 | Write a function split : int list -> int list * int list such that split l = (front, back) where l = back @ List.rev front and the length of back and front is List.length l / 2 or List.length l / 2 + 1 10 | Write a function dequeue : queue -> int * queue such that dequeue q = (x, q') where x is the front element of the queue q and q' corresponds to remaining elements. This function assumes that q is non empty. 11 | THE GIVEN PRELUDE 12 | 13 | type queue = int list * int list 14 | *) 15 | let is_empty (front, back) = 16 | List.length front = 0 && List.length back = 0;; 17 | 18 | let enqueue x (front, back) = 19 | (front, x :: back);; 20 | 21 | let split l = 22 | let mid = List.length l / 2 in 23 | let rec help i l' ls= 24 | match l' with 25 | | [] -> ([],[]) 26 | | (x::xs) -> 27 | if i < mid 28 | then help (i+1) xs (ls @ [x]) 29 | else (List.rev (x::xs), ls) 30 | in 31 | help 0 l [];; 32 | 33 | let dequeue (front, back) = 34 | match front with 35 | | [] -> let (x::xs) =List.rev back in (x,(front,List.rev xs)) 36 | | x::xs -> (x, (xs,back));; 37 | 38 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/Exercise/W3_S1_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | CLASSIC FUNCTIONS OVER LISTS (40/40 points) 3 | In this exercise, we implement the classic functions over lists. 4 | 5 | Write a function mem : int -> int list -> bool such that mem x l is true if and only if x occurs in l. 6 | Write a function append : int list -> int list -> int list such that append l1 l2 is the concatenation of l1 and l2. 7 | Write a function combine : int list -> int list -> (int * int) list such that combine l1 l2 is the list of pairs obtained by joining the elements of l1 and l2. This function assumes that l1 and l2 have the same length. For instance, combine [1;2] [3;4] = [(1, 3); (2, 4)]. 8 | Write a function assoc : (string * int) list -> string -> int option such that assoc l k = Some x if (k, x) is the first pair of l whose first component is k. If no such pair exists, assoc l k = None. 9 | *) 10 | let rec mem x l = 11 | match l with 12 | | [] -> false 13 | | (y::ys) -> 14 | if x = y then true else mem x ys;; 15 | 16 | let rec append l1 l2 = 17 | l1 @ l2;; 18 | 19 | let rec combine l1 l2 = 20 | match (l1,l2) with 21 | | ((x::xs),(y::ys)) -> (x,y) :: (combine xs ys) 22 | | _ -> [] ;; 23 | 24 | let rec assoc l k = 25 | match l with 26 | | x::xs -> 27 | let (s, i) = x in 28 | if (k = s) then Some i 29 | else assoc xs k 30 | | [] -> None;; 31 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/Exercise/W3_S2_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | SYMBOLIC MANIPULATION OF ARITHMETIC EXPRESSIONS (44/44 points) 3 | Abstract syntax trees are a convenient way to represent a syntactic expression in a structured way. 4 | Let us consider arithmetic expressions formed by the following rules: 5 | 6 | an integer is an arithmetic expression ; 7 | if lhs and rhs are arithmetic expressions then lhs + rhs is an arithmetic expression; 8 | if lhs and rhs are arithmetic expressions then lhs * rhs is an arithmetic expression. 9 | Such an expression can be represented by a value of type exp as defined in the given prelude (as well as the definition of 1 + 2 * 3 as an example). 10 | Write the expression 2 * 2 + 3 * 3 in a variable my_example. 11 | Write a function eval : exp -> int that computes the value of an arithmetic expression. The evaluation rules are: 12 | If the expression is an integer x, the evaluation is x. 13 | If the expression is lhs + rhs and lhs evaluates to x and rhs evaluates to y, then the evaluation is x + y. 14 | If the expression is lhs * rhs and lhs evaluates to x and rhs evaluates to y, then the evaluation is x * y. 15 | If an expression is of the form a * b + a * c then a * (b + c) is a factorized equivalent expression. 16 | Write a function factorize : exp -> exp that implements this transformation on its input exp if it has the shape a * b + a * c or does nothing otherwise. 17 | Write the reverse transformation of factorize, expand : exp -> exp, which turns an expression of the shape a * (b + c) into a * b + a * c. 18 | Implement a function simplify: exp -> exp which takes an expression e and: 19 | If e is of the shape e * 0 or 0 * e, returns the expression 0. 20 | If e is of the shape e * 1 or 1 * e, returns the expression e. 21 | If e is of the shape e + 0 or 0 + e, returns the expression e. 22 | and does nothing otherwise. 23 | Remarks: 24 | 25 | The symbols (a, b, c and e) can match any expressions, not just integers. 26 | these are a syntactical rewritings, so two expressions are considered equal if and only if they are exactly the same expressions (simply use the = operator to check that). 27 | The rewritings have to be done on the first level of the expression only, not recursively and not deeper in the expression. If the toplevel expression does not match the expected pattern, simply return the expression untouched. 28 | THE GIVEN PRELUDE 29 | 30 | type exp = 31 | | EInt of int 32 | | EAdd of exp * exp 33 | | EMul of exp * exp 34 | 35 | let example = 36 | EAdd (EInt 1, EMul (EInt 2, EInt 3)) 37 | *) 38 | 39 | let my_example = 40 | EAdd (EMul (EInt 2, EInt 2), EMul (EInt 3, EInt 3));; 41 | 42 | let rec eval e = 43 | match e with 44 | | EInt x -> x 45 | | EAdd (x, y) -> (eval x)+(eval y) 46 | | EMul (x, y) -> (eval x)*(eval y);; 47 | 48 | let factorize e = 49 | match e with 50 | | EAdd (EMul (a,b), EMul (c,d)) -> if a = c then EMul(a, EAdd(b, d)) else e 51 | | _ -> e;; 52 | 53 | let rec factorize2 e = 54 | match e with 55 | | EAdd(x, y) -> 56 | (match (x, y) with 57 | | (EMul(a,b), EMul(a',c)) -> 58 | if a=a' then EMul(factorize a,EAdd(factorize b,factorize c)) 59 | else EAdd(EMul(factorize a,factorize b), EMul(factorize a',factorize c)) 60 | | _ -> EAdd(factorize x,factorize y)) 61 | | EMul (x, y) -> EMul (factorize x,factorize y) 62 | | _ -> e;; 63 | 64 | let expand e = match e with 65 | | EMul(a,EAdd(b,c)) -> EAdd(EMul(a,b),EMul(a,c)) 66 | | _ -> e;; 67 | 68 | let simplify e = 69 | match e with 70 | | EMul(a,EInt 1) -> a 71 | | EMul(EInt 1,a) -> a 72 | | EMul(a,EInt 0) -> EInt 0 73 | | EMul(EInt 0,a) -> EInt 0 74 | | EAdd(EInt 0,a) -> a 75 | | EAdd(a,EInt 0) -> a 76 | | _ -> e;; -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/Exercise/W3_S2_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | TRIES (40/40 points) 3 | The data structure called trie is very convenient to represent a dictionary whose keys are strings. It is space-efficient way while providing a very fast lookup function. 4 | See the page on WikiPedia. 5 | In this exercise, we will implement such a data structure, assuming that we want to associate integers to the strings of the dictionary. 6 | Let us define a trie using two mutually defined types (given in the prelude): 7 | 8 | trie which represents a trie, that is a tree whose root may contain an integer and whose children are indexed by characters ; 9 | char_to_children which implements the associative data structure whose keys are characters and whose values are trie (childrens). 10 | As a trade-off between speed and memory consumption, we choose an associative list to represent the association between characters and children. 11 | The prelude also gives examples of empty trie and of another one that contains the following pairs (key, value): 12 | [("A", 15); ("to", 7); ("tea", 3);("ted", 4); ("ten", 12); ("i", 11); ("in", 5); ("inn", 9)]. 13 | Write a function children_from_char : char_to_children -> char -> trie option such that 14 | children_from_char m c = Some t if (c, t) is the first pair in m with c as a first component ; 15 | children_from_char m c = None if no such pair exists in m. 16 | Write a function update_children : char_to_children -> char -> trie -> char_to_children such that 17 | children_from_char (update_children m c t) c = Some t ; 18 | children_from_char (update_children m c t) c' = children_from_char m c' for c <> c'; 19 | If children_from_char m c = Some t then List.length (update_children m c t') = List.length m. 20 | Write a function lookup : trie -> string -> int option such that lookup trie w = Some i if i is the value of the key w in trie and lookup trie w = None if w is not a key of trie. 21 | To look for a key in a trie, iterate over the characters of the key from left to right. Given the current character c and the current node of the trie n, look for the children n for character c. If such a children exists, continue with that trie and the remainder of the key. If no such children exists, the key is not in the trie. When the characters of the key are entirely consumed, look at the root of the current trie. If there is an integer, this is the value you are looking for. If there is no integer, the key not in the trie. 22 | Write a function insert : trie -> string -> int -> trie such that lookup (insert trie w k) w = Some k and lookup (insert trie w k) w' = lookup trie w' for w <> w'. 23 | THE GIVEN PRELUDE 24 | 25 | type trie = Trie of int option * char_to_children 26 | and char_to_children = (char * trie) list 27 | 28 | let empty = 29 | Trie (None, []) 30 | 31 | let example = 32 | Trie (None, 33 | [('i', Trie (Some 11, 34 | [('n', Trie (Some 5, [('n', Trie (Some 9, []))]))])); 35 | ('t', 36 | Trie (None, 37 | [('e', 38 | Trie (None, 39 | [('n', Trie (Some 12, [])); ('d', Trie (Some 4, [])); 40 | ('a', Trie (Some 3, []))])); 41 | ('o', Trie (Some 7, []))])); 42 | ('A', Trie (Some 15, []))]) 43 | 44 | *) 45 | 46 | let rec children_from_char m c = 47 | match m with 48 | | [] -> None 49 | | (c', t)::xs -> 50 | if c' = c then Some t 51 | else children_from_char xs c;; 52 | 53 | 54 | let update_children m c t = 55 | if ((children_from_char m c) = None) then m@[(c,t)] 56 | else 57 | let rec help ml = 58 | match ml with 59 | | [] -> [] 60 | | (c',t')::xs -> 61 | if c'=c then (c,t)::xs 62 | else (c',t')::(help xs) 63 | in 64 | help m;; 65 | 66 | 67 | 68 | let lookup trie w = 69 | let rec find t idx = 70 | let Trie(value, children) = t in 71 | if idx = String.length w then 72 | value 73 | else 74 | match (children_from_char children (String.get w idx)) with 75 | | None -> None 76 | | Some t' -> find t' (idx + 1) 77 | in 78 | find trie 0;; 79 | 80 | 81 | let rec insert trie w v = 82 | let slen = String.length w 83 | and Trie(v',m) = trie in 84 | if slen = 0 then Trie(Some v, m) 85 | else 86 | let c = String.get w 0 87 | and s = String.sub w 1 (slen - 1) in 88 | let ot = children_from_char m c in 89 | match ot with 90 | | (Some t) -> Trie (v', update_children m c (insert t s v)) 91 | | None -> Trie (v', update_children m c (insert empty s v));; 92 | 93 | 94 | let insert2 trie w v = 95 | let len = String.length(w) in 96 | let rec help ctc pos = 97 | let ch = String.get w pos in 98 | match (children_from_char ctc ch) with 99 | | Some t -> 100 | let Trie(x, ctc') = t in 101 | if (pos = len - 1) then update_children ctc ch (Trie(Some v,ctc')) 102 | else update_children ctc ch (Trie(x, help ctc' (pos+1))) 103 | | None -> 104 | let rec loop i = 105 | if (i = len - 1) then (String.get w i, Trie(Some v,[]))::[] 106 | else (String.get w i,Trie (None, loop (i+1)))::[] 107 | in 108 | if (pos = len - 1) then update_children ctc ch (Trie(Some v, [])) 109 | else update_children ctc ch (Trie (None, loop (1 + pos))) 110 | in 111 | let Trie(num, ctc) = trie in 112 | if (len = 0) then Trie(Some v, ctc) 113 | else Trie(num, help ctc 0);; 114 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/Exercise/W3_S3.ml: -------------------------------------------------------------------------------- 1 | (* 2 | TYPE DIRECTED PROGRAMMING (40/40 points) 3 | In this exercise, you will experiment with type-directed programming. 4 | 5 | We give you the example program of the lecture in which two type definitions have been changed as in the given prelude. A case Tired has been added to type state, and a case Sleep has been added to type action. 6 | By clicking the typecheck button, you can notice that several warnings are issued by the OCaml compiler. Go through the code and fix these warnings as follow. 7 | 8 | Update apply_action so that the Sleep action turns a character from the Tired state to the Hungry state. 9 | Update possible_changes_for_character so that the Tired state behaves as the Hungry state. 10 | Update describe_state so that the description of the Tired state is "tired". 11 | Update tell_action so that tell_action Sleep is "took a nap". 12 | 13 | THE GIVEN PRELUDE 14 | 15 | type story = { 16 | context : context; 17 | perturbation : event; 18 | adventure : event list; 19 | conclusion : context; 20 | } 21 | and context = { characters : character list } 22 | and character = { name : string; state : state; location : location } 23 | and event = Change of character * state | Action of character * action 24 | and state = Happy | Hungry | Tired 25 | and action = Eat | GoToRestaurant | Sleep 26 | and location = Appartment | Restaurant 27 | *) 28 | 29 | let compatible_actions_for_character character context = 30 | match character with 31 | | { location = Restaurant } -> [Eat] 32 | | { location = Appartment } -> [GoToRestaurant] 33 | ;; 34 | 35 | let apply_action character = function 36 | | Eat -> 37 | { state = Happy; 38 | location = character.location; name = character.name } 39 | | GoToRestaurant -> 40 | { location = Restaurant; 41 | state = character.state; name = character.name } 42 | | Sleep -> 43 | { location = character.location; 44 | state = Hungry; name = character.name } 45 | ;; 46 | 47 | let compatible_actions context = 48 | let rec aux = function 49 | | [] -> [] 50 | | character :: cs -> 51 | let can_do = compatible_actions_for_character character context in 52 | let rec aux' = function 53 | | [] -> [] 54 | | a :: actions -> Action (character, a) :: aux' actions 55 | in 56 | aux' can_do 57 | in 58 | aux context.characters 59 | ;; 60 | 61 | let possible_changes_for_character character = 62 | match character with 63 | | { state = Happy } -> [Hungry] 64 | | { state = Hungry } -> [] 65 | | { state = Tired } -> [] 66 | ;; 67 | let apply_change character state = 68 | { name = character.name; state = state; location = character.location } 69 | ;; 70 | 71 | let possible_changes context = 72 | let rec aux = function 73 | | [] -> [] 74 | | character :: cs -> 75 | let possible_changes = possible_changes_for_character character in 76 | let rec aux' = function 77 | | [] -> [] 78 | | c :: changes -> Change (character, c) :: aux' changes 79 | in 80 | aux' possible_changes 81 | in 82 | aux context.characters 83 | ;; 84 | 85 | let character_of_event = function 86 | | Action (character, _) -> character 87 | | Change (character, _) -> character 88 | ;; 89 | 90 | let apply event context = 91 | let rec aux = function 92 | | [] -> assert false 93 | | character :: cs -> 94 | if character = character_of_event event then 95 | match event with 96 | | Action (_, action) -> apply_action character action :: cs 97 | | Change (_, change) -> apply_change character change :: cs 98 | else 99 | character :: aux cs 100 | in 101 | { characters = aux context.characters } 102 | ;; 103 | 104 | let rec is_one_of state states = 105 | match states with 106 | | [] -> false 107 | | state' :: ss -> state = state' || is_one_of state ss 108 | ;; 109 | 110 | let rec all_characters_are states = function 111 | | [] -> 112 | true 113 | | character :: cs -> 114 | is_one_of character.state states && all_characters_are states cs 115 | ;; 116 | 117 | let random_pick xs = 118 | List.nth xs (Random.int (List.length xs)) 119 | ;; 120 | 121 | let something_happens context = 122 | let what_can_happen = compatible_actions context @ possible_changes context in 123 | let event = random_pick what_can_happen in 124 | event, apply event context 125 | ;; 126 | let happy context = 127 | all_characters_are [Happy] context.characters 128 | ;; 129 | 130 | let rec end_story events context = 131 | if happy context then 132 | context, List.rev events 133 | else 134 | let event, context = something_happens context in 135 | end_story (event :: events) context 136 | ;; 137 | 138 | let make_story initial_context = 139 | let perturbation, context = something_happens initial_context in 140 | let conclusion, adventure = end_story [] context in 141 | { 142 | context = initial_context; 143 | perturbation = perturbation; 144 | adventure = adventure; 145 | conclusion = conclusion 146 | } 147 | ;; 148 | 149 | let describe_location = function 150 | | Appartment -> "at home" 151 | | Restaurant -> "at the restaurant" 152 | ;; 153 | let describe_state = function 154 | | Happy -> "happy" 155 | | Hungry -> "hungry" 156 | | Tired -> "tired" 157 | ;; 158 | let describe character = 159 | character.name ^ " was " 160 | ^ describe_location character.location 161 | ^ " and was " ^ describe_state character.state ^ ". " 162 | ;; 163 | 164 | let tell_context context = 165 | let rec aux = function 166 | | [] -> "" 167 | | character :: characters -> describe character ^ aux characters 168 | in 169 | aux context.characters 170 | ;; 171 | 172 | let tell_action = function 173 | | Eat -> "ate" 174 | | GoToRestaurant -> "went to the restaurant" 175 | | Sleep -> "took a nap" 176 | ;; 177 | 178 | let tell_event = function 179 | | Action (character, action) -> 180 | character.name ^ " " ^ tell_action action ^ ". " 181 | | Change (character, state) -> 182 | character.name ^ " was made " ^ describe_state state ^ ". " 183 | ;; 184 | 185 | let rec tell_adventure = function 186 | | [] -> "" 187 | | event :: adventure -> tell_event event ^ tell_adventure adventure 188 | ;; 189 | 190 | let tell story = 191 | "Once upon a time, " 192 | ^ tell_context story.context 193 | ^ "One day, something wrong happened. " 194 | ^ tell_event story.perturbation 195 | ^ tell_adventure story.adventure 196 | ^ "At the end, the peace was restored. " 197 | ^ tell_context story.conclusion 198 | ;; 199 | 200 | let story = tell (make_story { 201 | characters = [ 202 | { name = "Sophie"; location = Appartment; state = Happy }; 203 | { name = "Socrate"; location = Appartment; state = Happy }; 204 | ] 205 | });; 206 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/Exercise/W3_S4_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | BALANCED BINARY TREES (22/22 points) 3 | A binary tree t, of the 'a bt type given in the prelude, is either an empty tree, or the root of a tree with a value and two children subtrees. 4 | 5 | Write a function height : 'a bt -> int that computes the height of a tree. 6 | A tree is balanced if, for all internal node n, its two subtrees have the same height. Write a function balanced : 'a bt -> bool that tells if a tree is balanced. 7 | THE GIVEN PRELUDE 8 | 9 | type 'a bt = 10 | | Empty 11 | | Node of 'a bt * 'a * 'a bt ;; 12 | 13 | *) 14 | 15 | let rec height t = 16 | match t with 17 | | Empty -> 0 18 | | Node (l,_,r) -> max (1 + (height l)) (1 + (height r));; 19 | 20 | let rec balanced t = 21 | match t with 22 | | Empty -> true 23 | | Node (Empty, _ ,Empty) -> true 24 | | Node (Empty, _ ,_) -> false 25 | | Node (_, _ ,Empty) -> false 26 | | Node (l,_,r) -> balanced l && balanced r && height l = height r;; 27 | 28 | 29 | (* test *) 30 | balanced 31 | (Node 32 | (Node 33 | (Node (Node (Node (Empty, -5, Empty), 1, Node (Empty, 1, Empty)), -4, 34 | Node (Node (Empty, -3, Empty), -4, Node (Empty, -2, Empty))), 35 | 4, 36 | Node (Node (Node (Empty, -1, Empty), 4, Node (Empty, 1, Empty)), -3, 37 | Node (Node (Empty, -4, Empty), 3, Node (Empty, 3, Empty)))), 38 | 1, 39 | Node 40 | (Node (Node (Node (Empty, -1, Empty), 4, Node (Empty, -1, Empty)), -2, 41 | Node (Node (Empty, -1, Empty), 1, Node (Empty, -4, Empty))), 42 | -1, 43 | Node (Node (Empty, -2, Empty), -1, Node (Empty, -4, Empty)) 44 | ))) -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/Exercise/W3_S4_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | AN IMPLEMENTATION OF LIST WITH AN EFFICIENT CONCATENATION (56/56 points) 3 | Concatenating two standard OCaml lists takes a time proportional to the length of the first list. In this exercise, we implement a data structure for lists with a constant time concatenation. 4 | The preludes gives a type 'a clist, which is either a single element of type 'a, the concatenation of two 'a clist or an empty 'a clist. 5 | This representation of a list is not linear: it is a tree-like datastructure since the CApp constructor contains two values of type 'a clist. 6 | The sequence of elements contained in a value of type 'a clist is obtained by a depth-first traversal of the tree. For instance, the example given in the prelude, of type int clist is a valid representation for the sequence [1;2;3;4]. 7 | 8 | Write a function to_list : 'a clist -> 'a list which computes the 'a list that contains the same elements as the input 'a clist, in the same order. 9 | Write a function of_list : 'a list -> 'a clist which computes the 'a clist that contains the same elements as the input 'a list, in the same order. 10 | Write a function append : 'a clist -> 'a clist -> 'a clist such that: 11 | append CEmpty l = append l CEmpty = l 12 | append l1 l2 = CApp (l1, l2) otherwise 13 | Write a function hd : 'a clist -> 'a option that returns Some x where x is the first element of the input 'a clist, if it is not empty, and returns None otherwise. 14 | Write a function tl : 'a clist -> 'a clist option that returns Some l where l is the input sequence without its first element, if this input sequence is not empty, or returns None otherwise. 15 | THE GIVEN PRELUDE 16 | 17 | type 'a clist = 18 | | CSingle of 'a 19 | | CApp of 'a clist * 'a clist 20 | | CEmpty 21 | 22 | let example = 23 | CApp (CApp (CSingle 1, 24 | CSingle 2), 25 | CApp (CSingle 3, 26 | CApp (CSingle 4, CEmpty))) 27 | 28 | *) 29 | 30 | let rec to_list l = 31 | match l with 32 | | CSingle x -> [x] 33 | | CEmpty -> [] 34 | | CApp (xs,ys) -> (to_list xs) @ (to_list ys);; 35 | 36 | let rec of_list l = 37 | match l with 38 | | [] -> CEmpty 39 | | [x] -> CSingle x 40 | | (x::xs) -> CApp(CSingle x,of_list xs);; 41 | 42 | let append l1 l2 = 43 | match (l1,l2) with 44 | | (CEmpty, l) -> l 45 | | (l,CEmpty) -> l 46 | | _ -> CApp(l1,l2);; 47 | 48 | let hd l = 49 | match l with 50 | | CEmpty -> None 51 | | _ -> match (to_list l) with 52 | | (x::xs) -> Some x 53 | | [] -> None;; 54 | 55 | let tl l = 56 | match l with 57 | | CEmpty -> None 58 | | CSingle x -> Some CEmpty 59 | | _ -> match (to_list l) with 60 | | (_::xs) -> Some (of_list xs) 61 | | [] -> None;; 62 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/Exercise/W3_S5.ml: -------------------------------------------------------------------------------- 1 | (* 2 | ADVANCED PATTERNS (60/60 points) 3 | Let's rewrite some pattern matching with advanced constructs. 4 | 5 | Factorize the pattern matching of function simplify using or-patterns. It should boil down to three cases. 6 | The only_small_lists function takes a list as input and returns this list only if it contains two or less elements, otherwise the empty list is returned. Rewrite this function using or-patterns and an as-pattern. It should boil down to two cases. 7 | Turn the third case of no_consecutive_repetition into two distinct cases, dropping the if construct in favor of a when clause. 8 | THE GIVEN PRELUDE 9 | 10 | type e = EInt of int | EMul of e * e | EAdd of e * e 11 | *) 12 | 13 | let simplify = function 14 | | EMul (EInt 1, e) | EMul (e, EInt 1) | EAdd (EInt 0, e) | EAdd (e, EInt 0) -> e 15 | | EMul (EInt 0, e) | EMul (e, EInt 0) -> EInt 0 16 | | e -> e 17 | 18 | let only_small_lists = function 19 | | x::y::z::_ -> [] 20 | | ([] | _)as l -> l 21 | 22 | let rec no_consecutive_repetition = function 23 | | ([] | [_]) as l -> l 24 | | x :: ((y :: ys) as xs) when x = y -> 25 | no_consecutive_repetition xs 26 | | x :: xs -> 27 | x :: (no_consecutive_repetition xs) 28 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/OCaml_MOOC_W3_S0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W3_ALL/OCaml_MOOC_W3_S0.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/OCaml_MOOC_W3_S1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W3_ALL/OCaml_MOOC_W3_S1.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/OCaml_MOOC_W3_S2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W3_ALL/OCaml_MOOC_W3_S2.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/OCaml_MOOC_W3_S3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W3_ALL/OCaml_MOOC_W3_S3.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/OCaml_MOOC_W3_S4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W3_ALL/OCaml_MOOC_W3_S4.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/OCaml_MOOC_W3_S5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W3_ALL/OCaml_MOOC_W3_S5.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/aspat.ml: -------------------------------------------------------------------------------- 1 | let rec duplicate_head_at_the_end = function 2 | | [] -> [] 3 | | (x :: _) as l -> l @ [x];; 4 | let l = duplicate_head_at_the_end [1;2;3];; 5 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/bst.ml: -------------------------------------------------------------------------------- 1 | type 'a bst = 2 | | Empty 3 | | Node of 'a bst * 'a * 'a bst;; 4 | (* break *) 5 | let rec find_max = function 6 | | Empty -> assert false 7 | | Node (_, x, Empty) -> x 8 | | Node (_, x, r) -> find_max r;; 9 | (* break *) 10 | let rec insert x = function 11 | | Empty -> Node (Empty, x, Empty) 12 | | Node (l, y, r) -> 13 | if x = y then Node (l, y, r) 14 | else if x < y then Node (insert x l, y, r) 15 | else Node (l, y, insert x r);; 16 | (* break *) 17 | let rec delete x = function 18 | | Empty -> 19 | Empty 20 | | Node (l, y, r) -> 21 | if x = y then join l r 22 | else if x < y then Node (delete x l, y, r) 23 | else Node (l, y, delete x r) 24 | and join l r = 25 | match l, r with 26 | | Empty, r -> r 27 | | l, Empty -> l 28 | | l, r -> let m = find_max l in Node (delete m l, m, r);; 29 | (* break *) 30 | type contact = { name : string; phone_number : int } 31 | type database = contact bst;; 32 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/color.ml: -------------------------------------------------------------------------------- 1 | type color = Black | Gray | White;; 2 | let batman_s_color = Black;; 3 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/disjunctive.ml: -------------------------------------------------------------------------------- 1 | let remove_zero_or_one_head = function 2 | | 0 :: xs -> xs 3 | | 1 :: xs -> xs 4 | | l -> l;; 5 | let remove_zero_or_one_head' = function 6 | | 0 :: xs | 1 :: xs -> xs 7 | | l -> l;; 8 | let remove_zero_or_one_head'' = function 9 | | (0 | 1) :: xs -> xs 10 | | l -> l;; 11 | 12 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/either.ml: -------------------------------------------------------------------------------- 1 | type ('a, 'b) either = 2 | | Left of 'a 3 | | Right of 'b;; 4 | type square = { dimension : int };; 5 | type circle = { radius : int };; 6 | type shape = (square, circle) either;; 7 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/incompatiblePatterns.ml: -------------------------------------------------------------------------------- 1 | type data = None | Single of int | Pair of int * int;; 2 | let bad_arity (x : data) = 3 | match x with 4 | | None x -> x 5 | | Single x -> x 6 | | Pair (x, _) -> x;; 7 | let bad_argument_type (x : data) = 8 | match x with 9 | | Single true -> false 10 | | _ -> true;; 11 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/intList.ml: -------------------------------------------------------------------------------- 1 | type int_list = 2 | | EmptyList 3 | | SomeElement of int * int_list;; 4 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/intListLen.ml: -------------------------------------------------------------------------------- 1 | (* hide *) 2 | type int_list = 3 | | EmptyList 4 | | SomeElement of int * int_list;; 5 | (* show *) 6 | let rec length = function 7 | | EmptyList -> 0 8 | | SomeElement (x, l) -> 1 + length l;; 9 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/invalidArity.ml: -------------------------------------------------------------------------------- 1 | type ('a, 'b) t = 'a * 'b * 'a;; 2 | type u = (int, bool, string) t;; 3 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/light.ml: -------------------------------------------------------------------------------- 1 | type color = Black | Gray | White;; 2 | (* Black < Gray < White and forall x, not (x < x). *) 3 | let lighter c1 c2 = 4 | match (c1, c2) with 5 | | (Black, Black) -> false 6 | | (White, White) -> false 7 | | (Gray, Gray) -> false 8 | | (Black, _) -> true 9 | | (_, White) -> true 10 | | (White, Gray) -> false 11 | | (Gray, Black) -> false;; 12 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/listFastRev.ml: -------------------------------------------------------------------------------- 1 | let rec rev_aux accu = function 2 | | [] -> accu 3 | | x :: xs -> rev_aux (x :: accu) xs;; 4 | let rev l = rev_aux [] l;; 5 | let l = rev [1; 2; 3];; 6 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/listLen.ml: -------------------------------------------------------------------------------- 1 | let rec length = function 2 | | [] -> 0 3 | | x :: xs -> 1 + length xs;; 4 | let three = length [1; 2; 3];; 5 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/listRev.ml: -------------------------------------------------------------------------------- 1 | (* The '@' is a predefined operator that appends a list to another one. *) 2 | let rec rev = function 3 | | [] -> [] 4 | | x :: xs -> rev xs @ [ x ];; 5 | let l = rev [ 1; 2; 3 ];; 6 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/listUnique.ml: -------------------------------------------------------------------------------- 1 | let rec uniq = function 2 | | [] -> [] 3 | | [x] -> [x] 4 | | x :: x' :: xs -> 5 | if x = x' then 6 | uniq (x' :: xs) 7 | else 8 | x :: uniq (x' :: xs);; 9 | let l1 = uniq [1;2;2;3;4;3];; 10 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/money.ml: -------------------------------------------------------------------------------- 1 | type euro = Euro of float;; 2 | type dollar = Dollar of float;; 3 | let euro_of_dollar (Dollar d) = Euro (d /. 1.33);; 4 | let x = Dollar 4.;; 5 | let y = Euro 5.;; 6 | let invalid_comparison = (x < y);; 7 | let valid_comparison = (euro_of_dollar x < y);; 8 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/option.ml: -------------------------------------------------------------------------------- 1 | (* The following type is predefined. *) 2 | type 'a option = 3 | | None 4 | | Some of 'a;; 5 | 6 | let o1 = Some 42;; 7 | let o2 = None;; 8 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/query.ml: -------------------------------------------------------------------------------- 1 | (* hide *) 2 | type contact = { name : string; phone_number : int * int * int * int };; 3 | (* show *) 4 | type query = 5 | | Insert of contact 6 | | Delete of contact 7 | | Search of string;; 8 | (* break *) 9 | let luke = { name = "luke"; phone_number = (1, 2, 3, 4) } 10 | let query1 = Insert luke;; 11 | let query2 = Search "luke";; 12 | let query3 = Delete luke;; 13 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/storyTeller.ml: -------------------------------------------------------------------------------- 1 | type story = { 2 | context : context; 3 | perturbation : event; 4 | adventure : event list; 5 | conclusion : context; 6 | } 7 | and context = { characters : character list } 8 | and character = { name : string; state : state; location : location } 9 | and event = Change of character * state | Action of character * action 10 | and state = Happy | Hungry 11 | and action = Eat | GoToRestaurant 12 | and location = Appartment | Restaurant;; 13 | (* break *) 14 | let compatible_actions_for_character character context = 15 | match character with 16 | | { location = Restaurant } -> [Eat] 17 | | { location = Appartment } -> [GoToRestaurant] 18 | ;; 19 | (* break *) 20 | let apply_action character = function 21 | | Eat -> 22 | { state = Happy; 23 | location = character.location; name = character.name } 24 | | GoToRestaurant -> 25 | { location = Restaurant; 26 | state = character.state; name = character.name } 27 | ;; 28 | (* break *) 29 | let compatible_actions context = 30 | let rec aux = function 31 | | [] -> [] 32 | | character :: cs -> 33 | let can_do = compatible_actions_for_character character context in 34 | let rec aux' = function 35 | | [] -> [] 36 | | a :: actions -> Action (character, a) :: aux' actions 37 | in 38 | aux' can_do 39 | in 40 | aux context.characters 41 | ;; 42 | (* break *) 43 | let possible_changes_for_character character context = 44 | match character with 45 | | { state = Happy } -> [Hungry] 46 | | { state = Hungry } -> [] 47 | ;; 48 | let apply_change character state = 49 | { name = character.name; state = state; location = character.location } 50 | ;; 51 | (* break *) 52 | let possible_changes context = 53 | let rec aux = function 54 | | [] -> [] 55 | | character :: cs -> 56 | let possible_changes = possible_changes_for_character character context in 57 | let rec aux' = function 58 | | [] -> [] 59 | | c :: changes -> Change (character, c) :: aux' changes 60 | in 61 | aux' possible_changes 62 | in 63 | aux context.characters 64 | ;; 65 | (* break *) 66 | let character_of_event = function 67 | | Action (character, _) -> character 68 | | Change (character, _) -> character 69 | ;; 70 | (* break *) 71 | let apply event context = 72 | let rec aux = function 73 | | [] -> assert false 74 | | character :: cs -> 75 | if character = character_of_event event then 76 | match event with 77 | | Action (_, action) -> apply_action character action :: cs 78 | | Change (_, change) -> apply_change character change :: cs 79 | else 80 | character :: aux cs 81 | in 82 | { characters = aux context.characters } 83 | ;; 84 | (* break *) 85 | let rec is_one_of state states = 86 | match states with 87 | | [] -> false 88 | | state' :: ss -> state = state' || is_one_of state ss 89 | ;; 90 | (* break *) 91 | let rec all_characters_are states = function 92 | | [] -> 93 | true 94 | | character :: cs -> 95 | is_one_of character.state states && all_characters_are states cs 96 | ;; 97 | (* break *) 98 | let random_pick xs = 99 | List.nth xs (Random.int (List.length xs)) 100 | ;; 101 | let something_happens context = 102 | let what_can_happen = compatible_actions context @ possible_changes context in 103 | let event = random_pick what_can_happen in 104 | event, apply event context 105 | ;; 106 | let happy context = 107 | all_characters_are [Happy] context.characters 108 | ;; 109 | (* break *) 110 | let rec end_story events context = 111 | if happy context then 112 | context, List.rev events 113 | else 114 | let event, context = something_happens context in 115 | end_story (event :: events) context 116 | ;; 117 | (* break *) 118 | let make_story initial_context = 119 | let perturbation, context = something_happens initial_context in 120 | let conclusion, adventure = end_story [] context in 121 | { 122 | context = initial_context; 123 | perturbation = perturbation; 124 | adventure = adventure; 125 | conclusion = conclusion 126 | } 127 | ;; 128 | (* break *) 129 | let describe_location = function 130 | | Appartment -> "at home" 131 | | Restaurant -> "at the restaurant" 132 | ;; 133 | let describe_state = function 134 | | Happy -> "happy" 135 | | Hungry -> "hungry" 136 | ;; 137 | let describe character = 138 | character.name ^ " was " 139 | ^ describe_location character.location 140 | ^ " and was " ^ describe_state character.state ^ ". " 141 | ;; 142 | (* break *) 143 | let tell_context context = 144 | let rec aux = function 145 | | [] -> "" 146 | | character :: characters -> describe character ^ aux characters 147 | in 148 | aux context.characters 149 | ;; 150 | (* break *) 151 | let tell_action = function 152 | | Eat -> "ate" 153 | | GoToRestaurant -> "went to the restaurant" 154 | ;; 155 | (* break *) 156 | let tell_event = function 157 | | Action (character, action) -> 158 | character.name ^ " " ^ tell_action action ^ ". " 159 | | Change (character, state) -> 160 | character.name ^ " was made " ^ describe_state state ^ ". " 161 | ;; 162 | (* break *) 163 | let rec tell_adventure = function 164 | | [] -> "" 165 | | event :: adventure -> tell_event event ^ tell_adventure adventure 166 | ;; 167 | (* break *) 168 | let tell story = 169 | "Once upon a time, " 170 | ^ tell_context story.context 171 | ^ "One day, something wrong happened. " 172 | ^ tell_event story.perturbation 173 | ^ tell_adventure story.adventure 174 | ^ "At the end, the peace was restored. " 175 | ^ tell_context story.conclusion 176 | ;; 177 | (* break *) 178 | let story = tell (make_story { 179 | characters = [ 180 | { name = "Sophie"; location = Appartment; state = Happy }; 181 | { name = "Socrate"; location = Appartment; state = Happy }; 182 | ] 183 | });; 184 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/unboundTypeVariable.ml: -------------------------------------------------------------------------------- 1 | type 'a t = 'a * 'b;; 2 | -------------------------------------------------------------------------------- /OCaml_MOOC_W3_ALL/when.ml: -------------------------------------------------------------------------------- 1 | let rec push_max_at_the_end = function 2 | | ([] | [_]) as l -> l 3 | | x :: ((y :: _) as l) when x <= y -> x :: push_max_at_the_end l 4 | | x :: y :: ys -> y :: push_max_at_the_end (x :: ys);; 5 | let l = push_max_at_the_end [3;2;1] 6 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/Exercise/W4_S0.ml: -------------------------------------------------------------------------------- 1 | (* 2 | LAMBDA-EXPRESSIONS AS VALUES (20/20 points) 3 | In this exercise, we will define functions as values, also called lambda expressions, using the keyword function to do a pattern-matching on their argument. As a result, you are not allowed to use match ... with in your code. 4 | 5 | Define a function last_element: 'a list -> 'a that returns the last element of a list. Your function may return (invalid_arg "last_element") when the list is empty. 6 | Write a function is_sorted: 'a list -> bool that takes a list l as argument, and that checks that the list is sorted in increasing order according to the polymorphic comparison operator <. 7 | *) 8 | 9 | let rec last_element = function 10 | | [x] -> x 11 | | x::xs -> last_element xs 12 | | _ -> invalid_arg "last_element" 13 | ;; 14 | 15 | let rec is_sorted = function 16 | | x::y::ys -> if (xtrue 18 | ;; 19 | 20 | 21 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/Exercise/W4_S1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | USING FIRST CLASS FUNCTIONS (20/20 points) 3 | Write a function compose : ('a -> 'a) list -> ('a -> 'a) that takes as argument a list l of functions, and that returns the function that is the composition of the functions in l. For instance, compose [f;g;h] x = f (g (h x)). Or with concrete functions, compose [(fun x -> x+1);(fun x -> 3*x);(fun x -> x-1)] 2 = 4. 4 | Write a function fixedpoint : (float -> float) -> float -> float -> float that takes a function f of type float -> float and two floating-point arguments start and delta. The function fixedpoint applies repetitively f to the result of its previous application, starting from start, until it reaches a value y where the difference between y and (f y) is smaller than delta. In that case it returns the value of y. For instance, fixedpoint cos 0. 0.001 yields approximately 0.739 (ref). 5 | THE GIVEN PRELUDE 6 | 7 | type int_ff = int -> int 8 | *) 9 | 10 | let rec compose = function 11 | | f::fs -> (function x -> f (compose fs x)) 12 | | _ -> (function x -> x);; 13 | 14 | let rec fixedpoint f start delta = 15 | if abs_float(start -. (f start)) < delta then start 16 | else fixedpoint f (f start) delta;; 17 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/Exercise/W4_S2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | FUNCTIONS RETURNING FUNCTIONS (25/25 points) 3 | The following function checks the pairwise equality of the elements of two lists, on the common length of both lists: 4 | 5 | let rec equal_on_common l1 l2 = match l1,l2 with 6 | | [],_ -> true 7 | | _,[] -> true 8 | | h1::r1,h2::r2 -> h1=h2 && equal_on_common r1 r2 9 | Rewrite equal_on_common : 'a list -> 'a list -> bool by using nested function .. -> constructions. Using the match .. with construction or tuple patterns is forbidden. You can (and must) only call the operators && and =, and the function equal_on_common recursively. 10 | *) 11 | 12 | let rec equal_on_common = function 13 | | [] -> (function _ -> true) 14 | | x::xs -> (function 15 | | [] -> true 16 | | y::ys -> x = y && equal_on_common xs ys) 17 | ;; 18 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/Exercise/W4_S3_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | OPTIMIZING PARTIAL APPLICATIONS (35/35 points) 3 | Every triangle has a circumscribed circle, that is a circle that goes through the three points of a given triangle. Trigonometry tells us that the radius of this circle is s2⋅cos(a2)⋅2⋅cos(b2)⋅2⋅cos(c2) where a, b and c are the angles of the triangle, and s is its circumference. 4 | 5 | Define a function ccr: float -> float -> float -> float -> float that takes as arguments a, b, c and s, and returns the radius of circumscribed circle as described above. 6 | Update ccr so that it does as much work as possible when partially applied to each argument, and minimizes the total number of operations (multiplications, divisions and calls to cos). 7 | *) 8 | 9 | let ccr = fun a -> fun b -> fun c -> fun s -> 10 | s /. 8. /. cos(a /. 2.) /. cos(b /. 2.) /. cos(c /. 2.);; 11 | 12 | let ccr = fun a 13 | -> let resa = 8. *. cos (a/.2.) in fun b 14 | -> let resb = cos (b/.2.) *. resa in fun c 15 | -> let resc = cos (c/.2.) *. resb in fun s -> 16 | s /. resc;; 17 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/Exercise/W4_S3_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | A SMALL ARITHMETIC INTERPRETER (45/45 points) 3 | In this exercise, we will write a small program that computes some operations on integers. We will use a small datatype operation that describes all the operations to perform to compute the result. For example, suppose we want to do the following computation: 4 | mul (add 0 1) (mul 3 4) 5 | We can describe it as: Op ("mul", Op ("add", Value 0, Value 1), Op ("mul", Value 3, Value 4)) 6 | The Op constructor takes as a first argument a string, which is the name of the function that is stored in an environment. We suppose there exists a variable initial_env that contains some predefined functions. 7 | 8 | First of all, we need a way to find a function in an environment of type env, which is basically a list of tuples. Each of these tuples contains a string, which is the name of the function, and a value of type int -> int -> int, which is basically a function that takes two arguments of type int and returns an int as a result. 9 | Write a function lookup_function : string -> env -> (int -> int -> int) that returns the function associated to a name in an environment. If there is no function with the name given, you can return invalid_arg "lookup_function". 10 | Another useful feature would be to add functions to a given environment. Write the function add_function : string -> (int -> int -> int) -> env -> env that takes an environment e, a name for the function n and a function f, and returns a new environment that contains the function f that is associated to the name n. 11 | 12 | What you can notice now is that unless you put explicit annotations, those two previous functions should be polymorphic and work on any list of couples. Actually, lookup_function could have been written as List.assoc. 13 | Create a variable my_env: env that is the initial environment plus a function associated to the name "min" that takes two numbers and returns the lowest. You cannot use the already defined Pervasives.min function, nor any let .. in. Take advantage of lambda expressions! 14 | Now that we have correctly defined the operations to use the environment, we can write the function that computes an operation. Write a function compute: env -> operation -> int that takes an environment and an operation description, and computes this operation. The result is either: 15 | Directly the value. 16 | An operation that takes two computed values and a function from the environment. 17 | Let's be a bit more efficient and use the over-application: suppose a function id: 'a -> 'a, then id id will also have type 'a -> 'a, since the 'a is instantiated with 'a -> 'a . Using that principle, we can apply id to itself infinitely since it will always return a function. Write a function compute_eff : env -> operation -> int that takes an environment and an operation, and computes it. However, you cannot use let inside the function! 18 | THE GIVEN PRELUDE 19 | 20 | type operation = 21 | Op of string * operation * operation 22 | | Value of int 23 | 24 | type env = (string * (int -> int -> int)) list 25 | *) 26 | 27 | let rec lookup_function str = function 28 | | [] -> invalid_arg "lookup_function" 29 | | (s, int3)::xs -> 30 | if str = s then int3 31 | else lookup_function str xs;; 32 | 33 | let add_function name op env = 34 | let rec lookup myenv = 35 | match myenv with 36 | | [] -> [(name, op)] 37 | | (s, int3)::xs -> 38 | if s = name then (s, op)::xs 39 | else (s, int3)::(lookup xs) 40 | in lookup env ;; 41 | 42 | let my_env = 43 | initial_env @ [("min", fun x y -> if x>y then y else x)];; 44 | 45 | let rec compute env = function 46 | | Value v -> v 47 | | Op (str, op1, op2) -> lookup_function str env (compute env op1) (compute env op2);; 48 | 49 | let rec compute_eff env = function 50 | | Value v -> v 51 | | Op (str, op1, op2) -> 52 | lookup_function str env (compute_eff env op1) (compute_eff env op2);; 53 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/Exercise/W4_S4.ml: -------------------------------------------------------------------------------- 1 | (* 2 | USING AND WRITING THE MAP FUNCTION (30/30 points) 3 | The idea of this exercise is to use the principle of the map function to implement algorithms that transform data structures using higher-order functions. 4 | 5 | Using the function map from the module List, write a function wrap : 'a list -> 'a list list that transforms a list of elements 'ainto a list of singleton lists. 6 | For instance, wrap [1;2;3] is equal to [[1];[2];[3]] 7 | Consider the definition of the type tree given in the prelude. It represents binary trees carrying data items, on its internal nodes, and on its leaves. 8 | Write a function tree_map : ('a -> 'b) -> 'a tree -> 'b tree such that tree_map f t yields a tree of the same structure as t, but with all its data values x replaced by f x 9 | For example, suppose a function string_of_int : int -> string, that takes an integer and generates the string that represent this integer. Applied to tree_map and a tree of integers (i.e. of type int tree), it would yield a tree of strings (i.e. of type string tree). 10 | THE GIVEN PRELUDE 11 | 12 | type 'a tree = 13 | Node of 'a tree * 'a * 'a tree 14 | | Leaf of 'a;; 15 | *) 16 | 17 | let wrap l = 18 | List.map (function x -> [x]) l;; 19 | 20 | let rec tree_map f = function 21 | | Leaf l -> Leaf (f l) 22 | | Node (t1, n, t2) -> Node (tree_map f t1, f n, tree_map f t2);; 23 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/Exercise/W4_S5_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | USING FOLD TO PRODUCE LISTS (30/30 points) 3 | The idea of this exercise is to write functions that iterate on lists, using the fold_left and fold_right functions from the List module. 4 | 5 | Write a function filter : ('a -> bool) -> 'a list -> 'a list that takes a predicate p (a function returning a boolean) and a list l and returns all the elements of l that satisfy p (for which p returns true). 6 | Define, using List.fold_right, a function partition : ('a -> bool) -> 'a list -> 'a list * 'a list that takes a predicate p and a list l, and that partitions l by p. It returns a pair of two lists (lpos,lneg), where lpos is the list of all elements of l that satisfy p, and lneg is the list of all elements that do not satisfy p. 7 | One way of sorting a list is as follows: 8 | The empty list is already sorted. 9 | If the list l has a head h and a rest r, then a sorted version of l can be obtained in three parts: 10 | first a sorted version of all elements of r that are smaller or equal to h, 11 | then h, 12 | then a sorted version of all elements of r that are greater than h. 13 | Write a function sort:'a list-> 'a list that implements this algorithm, using the function partition of the previous question. This sorting algorithm is also known as Quicksort where the pivot is always the first element of the list. 14 | *) 15 | 16 | let filter p l = 17 | List.fold_left 18 | (fun acc ele -> if p ele then ele::acc else acc) 19 | [] 20 | l;; 21 | 22 | let partition p l = 23 | List.fold_right 24 | (fun ele (left,right) -> if p ele then (ele::left, right) else (left, ele::right)) 25 | l 26 | ([],[]);; 27 | 28 | let rec sort = function 29 | | [] -> [] 30 | | x::xs -> let (min, max) = partition (function y -> y < x) xs in 31 | sort min @ (x :: sort max);; 32 | 33 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/Exercise/W4_S5_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | USING FOLD TO CHECK PREDICATES (75/75 points) 3 | Using List.fold_left, write a function for_all : ('a -> bool) -> 'a list -> bool. It takes as argument a list l of type 'a list, and a predicate p of type 'a -> bool. It must return true if and only if all elements of l satisfy the predicate p. 4 | Using List.fold_left, write a function exists : ('a -> bool) -> 'a list -> bool. It takes as argument a list l of type 'a list, and a predicate p of type 'a -> bool. It must returns true if at least one element of l satisfies the predicate p. 5 | Write a function sorted : ('a -> 'a -> int) -> 'a list -> bool, using List.fold_left that checks that a list of elements l of type 'a is sorted, according to an ordering function cmp of type 'a -> 'a -> int. 6 | The ordering function returns: 7 | 1 (or any positive number) if the first element is greater than the second, 8 | -1 (or any negative number) if the first element is lesser than the second, 9 | and 0 otherwise. 10 | For the fold_left part, you can use the type 'a option as the accumulator: at each iteration of fold_left, if the list if sorted until now, the acccumulator is either Some v, where v is the previous element, or None otherwise. 11 | Remember, the empty list is sorted, so you can use the list with at least one element to check using fold_left. 12 | *) 13 | 14 | let for_all p l = 15 | List.fold_left 16 | (fun acc ele -> acc && p ele) 17 | true 18 | l;; 19 | 20 | let exists p l = 21 | List.fold_left 22 | (fun acc ele -> acc || p ele) 23 | false 24 | l;; 25 | 26 | let sorted cmp = function 27 | | [] -> true 28 | | x::xs -> 29 | let r = (List.fold_left 30 | (fun acc ele -> 31 | match acc with 32 | | Some ans when (cmp ans ele) <= 0 -> Some ele 33 | | _-> None) 34 | (Some x) xs) 35 | in 36 | if r=None then false else true;; 37 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/OCaml_MOOC_W4_S0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W4_ALL/OCaml_MOOC_W4_S0.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/OCaml_MOOC_W4_S1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W4_ALL/OCaml_MOOC_W4_S1.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/OCaml_MOOC_W4_S2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W4_ALL/OCaml_MOOC_W4_S2.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/OCaml_MOOC_W4_S3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W4_ALL/OCaml_MOOC_W4_S3.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/OCaml_MOOC_W4_S4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W4_ALL/OCaml_MOOC_W4_S4.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/OCaml_MOOC_W4_S5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W4_ALL/OCaml_MOOC_W4_S5.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/arg.ml: -------------------------------------------------------------------------------- 1 | let apply_twice f x = f (f x);; 2 | 3 | apply_twice (function x -> 2*x) 1;; 4 | 5 | let rec apply_n_times f n x = 6 | if n <= 0 7 | then x 8 | else apply_n_times f (n-1) (f x);; 9 | 10 | apply_n_times (function x -> 2*x) 10 1;; 11 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/associative.ml: -------------------------------------------------------------------------------- 1 | let double = function x -> 2*x;; 2 | 3 | double double 5;; 4 | 5 | double (double 5);; 6 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/counting.ml: -------------------------------------------------------------------------------- 1 | (* count elements of l satisfying p *) 2 | let countif p l = List.fold_left 3 | (fun counter element -> if p element then counter+1 else counter) 4 | 0 5 | l 6 | ;; 7 | 8 | countif (function x -> x>0) [3;-17;42;-73;-256];; 9 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/eval.ml: -------------------------------------------------------------------------------- 1 | type expr = 2 | | Var of string 3 | | Add of expr * expr;; 4 | 5 | let rec eval = fun environment expr -> match expr with 6 | | Var x -> List.assoc x environment 7 | | Add(e1,e2) -> (eval environment e1) 8 | + (eval environment e2);; 9 | 10 | eval [("x",2); ("y",5)] 11 | (Add (Var "x", Add (Var "x", Var "y")));; 12 | 13 | let rec eval = 14 | function environment -> 15 | function expr -> match expr with 16 | | Var x -> List.assoc x environment 17 | | Add(e1,e2) -> (eval environment e1) 18 | + (eval environment e2);; 19 | 20 | eval [("x",2); ("y",5)] 21 | (Add (Var "x", Add (Var "x", Var "y")));; 22 | 23 | let rec eval = function environment -> function 24 | | Var x -> List.assoc x environment 25 | | Add(e1,e2) -> (eval environment e1) 26 | + (eval environment e2);; 27 | 28 | eval [("x",2); ("y",5)] 29 | (Add (Var "x", Add (Var "x", Var "y")));; 30 | 31 | let rec eval environment = function 32 | | Var x -> List.assoc x environment 33 | | Add(e1,e2) -> (eval environment e1) 34 | + (eval environment e2);; 35 | 36 | eval [("x",2); ("y",5)] 37 | (Add (Var "x", Add (Var "x", Var "y")));; 38 | 39 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/foldleft.ml: -------------------------------------------------------------------------------- 1 | (* defined in library as List.fold_left *) 2 | let rec fold_left f b = function 3 | | [] -> b 4 | | h::r -> fold_left f (f b h) r;; 5 | 6 | fold_left (+) 0 [1;2;3;4];; 7 | 8 | let reverse = fold_left (fun x y -> y::x) [];; 9 | 10 | reverse [1;2;3;4;5];; 11 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/foldright.ml: -------------------------------------------------------------------------------- 1 | let rec fold_right f l b = match l with 2 | | [] -> b 3 | | h::r -> f h (fold_right f r b);; 4 | 5 | fold_right (fun x y -> x::y) [1;2;3;4] [];; 6 | 7 | fold_right (+) [1;2;3;4] 0;; 8 | 9 | fold_right ( * ) [1;2;3;4] 1;; 10 | 11 | let concat = fold_right (fun x y -> x::y);; 12 | 13 | concat [1;2;3;4] [5;6;7;8];; 14 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/innerproduct.ml: -------------------------------------------------------------------------------- 1 | let product v1 v2 = 2 | List.fold_left (+) 0 (List.map2 ( * ) v1 v2);; 3 | 4 | product [2;4;6] [1;3;5];; 5 | 6 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/lambda1.ml: -------------------------------------------------------------------------------- 1 | function x -> x+1;; 2 | 3 | function y -> [ [y+2; y+3]; [y; y*y]];; 4 | 5 | (function x -> 2*x) 5;; 6 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/lambda2.ml: -------------------------------------------------------------------------------- 1 | let double x = 2*x;; 2 | 3 | double 3;; 4 | 5 | let double = (function x -> 2*x);; 6 | 7 | double 3;; 8 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/list.ml: -------------------------------------------------------------------------------- 1 | let fl = [(function x -> x+1);(function x -> 2*x)];; 2 | 3 | (List.hd fl) 17;; 4 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/listegal.ml: -------------------------------------------------------------------------------- 1 | let egal l1 l2 = List.sort compare l1 = List.sort compare l2;; 2 | 3 | let f = egal [783; 42; 17];; 4 | 5 | f [17;42;783];; 6 | 7 | let egalp l1 = 8 | let l1sorted = List.sort compare l1 9 | in function l2 -> l1sorted = List.sort compare l2;; 10 | 11 | let f = egalp [783; 42; 17];; 12 | 13 | f [17;42;783];; 14 | 15 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/map.ml: -------------------------------------------------------------------------------- 1 | (* defined in library as List.map *) 2 | let rec map f = function 3 | | [] -> [] 4 | | h::r -> (f h)::(map f r);; 5 | 6 | map (function x -> x*x) [1;2;3;4;5];; 7 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/map2.ml: -------------------------------------------------------------------------------- 1 | (* defined in library as List.map2 *) 2 | let rec map2 f l1 l2 = match (l1,l2) with 3 | | [],[] -> [] 4 | | h1::r1,h2::r2 -> (f h1 h2)::(map2 f r1 r2) 5 | | _ -> raise (Invalid_argument "List.map2");; 6 | 7 | map2 (fun x y -> x+y) [1;2;3] [10;20;30];; 8 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/matrixsum.ml: -------------------------------------------------------------------------------- 1 | let msum = List.map2 (List.map2 (+));; 2 | 3 | msum [ [1;2]; [3;4]] [[10;20]; [30;40]];; 4 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/partial.ml: -------------------------------------------------------------------------------- 1 | let f1 = fun x y z -> x + y * z;; 2 | 3 | let f2 = f1 1;; 4 | 5 | let f3 = f2 2;; 6 | 7 | f3 4;; 8 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/pattern.ml: -------------------------------------------------------------------------------- 1 | let rec length = function 2 | | [] -> 0 3 | | _::r -> 1+ length r 4 | ;; 5 | 6 | length [17; 42; 73];; 7 | 8 | type expr = 9 | | Int of int 10 | | Add of expr * expr 11 | 12 | let rec eval = function 13 | | Int n -> n 14 | | Add(e1,e2) -> (eval e1) + (eval e2);; 15 | 16 | eval (Add (Add (Int 2, Int 5), Int 7));; 17 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/powerset.ml: -------------------------------------------------------------------------------- 1 | let rec sublists = function 2 | | [] -> [ [] ] 3 | | h::r -> 4 | let rp = sublists r in 5 | rp@(List.map (function l -> h::l) rp);; 6 | 7 | sublists [1;2;3];; 8 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/reduction.ml: -------------------------------------------------------------------------------- 1 | let f1 = fun x y -> (x / 0) + y;; 2 | 3 | let f2 = f1 17;; 4 | 5 | f2 42;; 6 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/result.ml: -------------------------------------------------------------------------------- 1 | let compose f g = (function x -> f(g x));; 2 | 3 | compose (function x->x+1) (function x->2*x);; 4 | 5 | (compose (function x->x+1) (function x->2*x)) 10;; 6 | 7 | compose (function x-> x+1) (function x -> x *. 3.14);; 8 | 9 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/return.ml: -------------------------------------------------------------------------------- 1 | let f1 = function n -> (function x -> n+x);; 2 | 3 | (f1 17) 73;; 4 | 5 | f1 17 73;; 6 | 7 | let f2 = fun n x -> n+x;; 8 | 9 | f2 17 73;; 10 | 11 | (f2 17) 73;; 12 | 13 | -------------------------------------------------------------------------------- /OCaml_MOOC_W4_ALL/vectorsum.ml: -------------------------------------------------------------------------------- 1 | let vsum = List.map2 (+);; 2 | 3 | vsum [1;2;3] [10;20;30];; 4 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/Exercise/W5_S1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | UNRAVELING THE AUTOMATIC GRADER (60/60 points) 3 | In this exercise, we will unveil the basics of the grading system. 4 | 5 | Note: This exercise is about exceptions, but it uses the unit type that is only presented in the next sequence. 6 | 7 | For each question, we call both your function and a reference function on a list of randomly sampled test cases, and observe the results. We also have to handle the case where a function raises an exception instead of producing a result. Sometimes, we even expect your function to raise an exception, and want to compare it to the exception raised by the reference function. 8 | For this, we use the 'a result type given in the prelude. 9 | Define a function exec: ('a -> 'b) -> 'a -> 'b result, that calls the given function on the given argument, and returns Ok with the result if everything went well, and Error with the exception raised, if there was one. 10 | To be able to provide you with the nice error reports, we use an intermediate type for producing reports, similar to the one given in the prelude. 11 | Define a function compare with the following signature. 12 | compare : 'a result -> 'a result -> ('a -> string) -> message 13 | This function will take first the user function's result and then the reference function's result. It also takes a printer compatible with the return type, to display the results as in one the following cases. 14 | ("got correct value 13", Successful) 15 | ("got unexpected value 13", Failed) 16 | ("got correct exception Exit", Successful) 17 | ("got unexpected exception Exit", Failed) 18 | You must respect the exact wording for your solution to be accepted. To display exceptions, you can use the provided exn_to_string function. 19 | Then we define random samplers for each type of data that will be passed to your function. For a given type 'a, a random sampler simply has type unit -> 'a, an imperative function that returns a new value of type 'a every time you give it a unit. 20 | Define a function test with the following signature. 21 | test : ('a -> 'b) -> ('a -> 'b) -> (unit -> 'a) -> ('b -> string) -> report 22 | This function must proceed to exactly 10 tests, calling the sampler each time, and return the list of messages. For each sample, you will exec the user function (the first parameter), then exec the reference function, and compare the results. It will then return the list containing the 10 comparison messages. 23 | Your solution must respect the constraint that the first call to the sampler corresponds to the first message of the list, the second to the second, etc. Be cautious about not reversing the list. And since the sampler is an imperative, remember to use let ... in constructs if necessary, to force the order of evaluation. 24 | THE GIVEN PRELUDE 25 | 26 | type report = message list 27 | and message = string * status 28 | and status = Successful | Failed 29 | 30 | type 'a result = Ok of 'a | Error of exn 31 | *) 32 | let exec f x = 33 | try Ok (f x) with e -> Error e ;; 34 | 35 | let compare user reference to_string = match user,reference with 36 | | (Ok a, Ok b) -> 37 | if (a=b) then ("got correct value "^(to_string a), Successful) 38 | else ("got unexpected value "^(to_string a), Failed) 39 | | (Error a, Error b) -> 40 | if (a=b) then ("got correct exception "^(exn_to_string a), Successful) 41 | else ("got unexpected exception "^(exn_to_string a), Failed) 42 | | (Error a, _) -> ("got unexpected exception "^(exn_to_string a), Failed) 43 | | (Ok a, _) -> ("got unexpected value "^(to_string a), Failed);; 44 | 45 | let test user reference sample to_string = 46 | let rec loop x acc = 47 | if x = 0 then List.rev acc 48 | else let sam = sample () in 49 | loop (x - 1) 50 | ((compare (exec user sam) (exec reference sam) to_string) :: acc) 51 | in 52 | loop 10 [];; 53 | 54 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/Exercise/W5_S2_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | PRINTING LISTS (200/200 points) 3 | Write a function print_int_list : int list -> unit that takes a list of integers as input, and prints all the elements of the list, each on its own line. 4 | Write a function print_every_other : int -> int list -> unit that takes a value k and a list of integers as input, and prints the elements of the list that are in positions multiple of k, each on its own line. Note: the first element of a list is at the position 0, not 1. 5 | Write a function print_list : ('a -> unit) -> 'a list -> unit that takes a printer of values of some type 'a and a list of such values as input, and prints all the elements of the list, each on its own line. 6 | 7 | *) 8 | 9 | let rec print_int_list = function 10 | | [] -> () 11 | | x::xs -> print_int x; print_newline(); print_int_list xs;; 12 | 13 | 14 | let print_every_other k l = 15 | let rec help n = function 16 | | [] -> () 17 | | x :: xs -> if (n = k) then (print_int x ; print_newline () ; help 1 xs) 18 | else help (n + 1) xs 19 | in help k l;; 20 | 21 | 22 | let rec print_list print = function 23 | | [] -> () 24 | | x::xs -> (print x ; print_newline () ; print_list print xs) 25 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/Exercise/W5_S3_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | PRINTING WITH LOOPS (105/105 points) 3 | Using the for loop construct, write an output_multiples : int -> int -> int -> unit function that prints all the multiples of x in the integer interval n ... m, separated by commas (','). 4 | Define a higher order function display_sign_until_zero: (int -> int) -> int -> unit that takes a function f, an integer m and applies f from 0 to m using a for loop. The function will print "negative" if the result of f if strictly negative and "positive" if strictly positive. Each print should appear on a new line. 5 | Your function has to stop displaying the signs as soon as f returns 0. In this case, it must print a last "zero". 6 | To implement this, you will define your own exception, raise it from inside the loop to break it, and catch it outside of the loop so that the function returns a successful (). You cannot use a predefined exception. 7 | THE GIVEN PRELUDE 8 | 9 | let is_multiple i x = i mod x = 0 10 | *) 11 | let output_multiples x n m = 12 | for i = n to m do 13 | if(i mod x = 0) then (print_int i; print_char ',') 14 | else () 15 | done;; 16 | 17 | exception Zero;; 18 | 19 | let display_sign_until_zero f m = 20 | try 21 | for i = 0 to m do 22 | let res = f i in 23 | if res > 0 then 24 | (print_string "positive"; 25 | print_newline()) 26 | else if res < 0 then 27 | (print_string "negative"; 28 | print_newline()) 29 | else raise Zero 30 | done 31 | with Zero -> print_string "zero";; 32 | 33 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/Exercise/W5_S3_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | PRODUCING FINE ASCII ART (175/175 points) 3 | In this exercise, we will display black and white images as text, where a black dot is printed as a '#' and a white dot as a ' '. 4 | 5 | Instead of using imperative constructs for storing our images, images will simply be functions that take an x and a y and return a boolean that indicates if the function is black or white at this point. 6 | This is materialized by the image type alias given in the prelude. 7 | We will only use imperative features to display them. 8 | 9 | Define a higher order function display_image: int -> int -> image -> unit that takes an integer width, another one height, a function which takes an x and a y, and renders (prints) the boolean function as a series of lines, using two nested for loops. 10 | Each line corresponds to a y, the first line printed being for y = 0, the last one for y = height. 11 | In each line, the first character printed must be for x = 0, the last one for x = width. When the function result is true, a sharp ('#') must be displayed, and a space otherwise. 12 | To try your function, the prelude defines sample images and image builders. 13 | For instance, the image disk 5 5 5 would be displayed as the following ASCII art, when rendered between coordinates 0 <= x <= 10 and 0 <= y <= 10. 14 | # 15 | ####### 16 | ######### 17 | ######### 18 | ######### 19 | ########### 20 | ######### 21 | ######### 22 | ######### 23 | ####### 24 | # 25 | Now, we want to blend images to compose complex images from simple ones. For this, we will use the blend type given the prelude. 26 | If we take two functions f and g, we have that: 27 | Image f 28 | is the blended image looking exactly like f. 29 | And (Image f, Image g) 30 | is the blended image that is black only where both f and g are both black. 31 | Or (Image f, Image g) 32 | is the blended image that is black wherever either f or g or both are black. 33 | Rem (Image f, Image g) 34 | is the blended image that is black wherever f is black and g is not. 35 | Write a recursive render : blend -> int -> int -> bool function, that tells, for a given x and y the boolean color of the point, considering the given blended image. 36 | Define a function display_blend: int -> int -> blend -> unit that takes a width, another one height, a blended image, and displays it by combining the two previous functions. 37 | As an example, the blend display_blend 10 10 (Rem (Image all_black, Image (disk 5 5 5))) would be displayed as the following ASCII art. 38 | ##### ##### 39 | ## ## 40 | # # 41 | # # 42 | # # 43 | 44 | # # 45 | # # 46 | # # 47 | ## ## 48 | ##### ##### 49 | Bonus question: Did you see that the type of render is actually equivalent to blend -> image? 50 | 51 | THE GIVEN PRELUDE 52 | 53 | type image = int -> int -> bool ;; 54 | 55 | let all_white = fun x y -> false ;; 56 | 57 | let all_black = fun x y -> true ;; 58 | 59 | let checkers = fun x y -> y/2 mod 2 = x/2 mod 2 ;; 60 | 61 | let square cx cy s = fun x y -> 62 | let minx = cx - s / 2 in 63 | let maxx = cx + s / 2 in 64 | let miny = cy - s / 2 in 65 | let maxy = cy + s / 2 in 66 | x >= minx && x <= maxx && y >= miny && y <= maxy 67 | ;; 68 | 69 | let disk cx cy r = fun x y -> 70 | let x' = x - cx in 71 | let y' = y - cy in 72 | (x' * x' + y' * y') <= r * r 73 | ;; 74 | 75 | type blend = 76 | | Image of image 77 | | And of blend * blend 78 | | Or of blend * blend 79 | | Rem of blend * blend 80 | ;; 81 | *) 82 | 83 | let display_image width height f_image = 84 | for y = 0 to height do 85 | for x = 0 to width do 86 | if f_image x y then print_string "#" 87 | else print_string " " 88 | done; 89 | print_newline() 90 | done;; 91 | 92 | let rec render blend x y = 93 | match blend with 94 | | Image im -> im x y 95 | | And (b1, b2) -> (render b1 x y) && (render b2 x y) 96 | | Or (b1, b2) -> (render b1 x y) || (render b2 x y) 97 | | Rem (b1, b2) -> (render b1 x y) && (not (render b2 x y));; 98 | 99 | let display_blend width height blend = 100 | display_image width width (render blend);; -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/Exercise/W5_S4_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | ROTATING THE CONTENTS OF AN ARRAY (22/22 points) 3 | In this exercise, you will improve the code shown in the course (and given in the template) for rotating arrays. 4 | 5 | There is something perfectible with the code of rotate. 6 | Find what, and fix the function!. 7 | Define rotate_by: 'a array -> int -> unit adding a parameter that allows to rotate by n positions. 8 | For instance, rotate_by [|1;2;3;4|] 3 should yield [|4;1;2;3|]. 9 | *) 10 | let rotate a = 11 | if a = [||] then () 12 | else 13 | let n = Array.length a in 14 | let v = a.(0) in 15 | for i = 0 to n-2 do 16 | a.(i) <- a.(i+1) 17 | done; 18 | a.(n-1) <-v ;; 19 | 20 | let rec rotate_by a n = 21 | let loop = 22 | if n < 0 then (Array.length a + n) else n 23 | in 24 | for i = 1 to loop do 25 | rotate a 26 | done;; 27 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/Exercise/W5_S4_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | IMPLEMENTING A STACK WITH AN ARRAY (50/50 points) 3 | In this exercise, we will encode imperative stacks of ints using the type stack = int array as defined in the prelude. 4 | 5 | We will use the first cell (cell 0) to store the number of items in the stack. Then the cells of the array starting from 1 will be used to store the elements in the stack. The bottom element of the stack will be stored at position 1. 6 | 7 | The stack will thus have a maximum capacity, being the length of the array minus one. 8 | 9 | An empty stack of capacity 4 would match the following pattern: 10 | [| 0 ; _ ; _ ; _ ; _|] 11 | A stack of capacity 4 containing 1 at the bottom, then 2 and then 3 at the top would match the following pattern: 12 | [| 3 ; 1 ; 2 ; 3 ; _|] 13 | Define a function create : int -> stack that creates a new stack of the given maximum capacity. 14 | Define a function push : stack -> int -> unit that adds an element as the top of the stack. 15 | The function must fail with the exception Full given in the prelude if nothing can be added to the stack. 16 | Define a function append : stack -> int array -> unit that adds an array of integers as the top of the stack. The first element of the array must be at the top of the stack, the others in order, up to the last element, which will be the lowest in the stack. In other words, the last element of the array should be pushed first, etc. 17 | The function must fail with the exception Full given in the prelude if some elements could not fit in the stack. But in this case, it should still fill the stack with as many elements as possible. 18 | Define a function pop : stack -> int that takes an element as the top of the stack, removes it from the stack, and return it. 19 | The function must fail with the exception Empty given in the prelude if nothing can be taken from the stack. 20 | THE GIVEN PRELUDE 21 | 22 | type stack = int array 23 | exception Full 24 | exception Empty 25 | *) 26 | let create size = 27 | Array.make (size+1) 0;; 28 | 29 | let push buf elt = 30 | if buf.(0) + 1 >= Array.length buf then raise Full 31 | else 32 | (buf.(buf.(0) + 1) <- elt; 33 | buf.(0) <- buf.(0) + 1) ;; 34 | 35 | let append buf arr = 36 | let l = Array.length arr in 37 | for i = l - 1 downto 0 do 38 | push buf arr.(i) 39 | done;; 40 | 41 | let pop buf = 42 | if buf.(0) = 0 then raise Empty 43 | else 44 | (let a = buf.(buf.(0)) in 45 | buf.(buf.(0)) <- 0; 46 | buf.(0) <- buf.(0) - 1; 47 | a) ;; 48 | 49 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/Exercise/W5_S5.ml: -------------------------------------------------------------------------------- 1 | (* 2 | IMPLEMENTING MUTABLE LISTS (80/80 points) 3 | Using mutable record fields, we can define the type of a list data structure with explicit pointers, as defined by the type 'a xlist given in the prelude. 4 | 5 | The empty list is written: 6 | 7 | { pointer = Nil } 8 | 9 | The singleton list containing only "one" is written: 10 | { pointer = List (1, { pointer = Nil }) } 11 | 12 | The list containing the elements 1, then 2 then 3 is written: 13 | { pointer = 14 | List (1, { pointer = 15 | List (2, { pointer = 16 | List (3, { pointer = 17 | Nil }) }) }) } 18 | 19 | Define head : 'a xlist -> 'a that returns the first element of the list if it exists, or fails with Empty_xlist. 20 | This function does not modify the list. 21 | Define tail : 'a xlist -> 'a xlist that returns the list without its first element if it exists, or fails with Empty_xlist. 22 | This function does not modify the list. 23 | Define add : 'a -> 'a xlist -> unit that modifies the list in place to add an element at the front. 24 | Define chop : 'a xlist -> unit that modifies the list to remove its front element, or fails with Empty_xlist. 25 | Define append : 'a xlist -> 'a xlist -> unit, a destructive concatenation operation that modifies the last pointer of the first list to point to the beginning of the second list. 26 | Define filter : ('a -> bool) -> 'a xlist -> unit, a destructive filter operation on lists that removes from the list all elements that do not satisfy the boolean predicate passed as parameter. 27 | THE GIVEN PRELUDE 28 | 29 | type 'a xlist = 30 | { mutable pointer : 'a cell } 31 | and 'a cell = 32 | | Nil 33 | | List of 'a * 'a xlist ;; 34 | 35 | let nil () = 36 | { pointer = Nil } ;; 37 | 38 | let cons elt rest = 39 | { pointer = List (elt, rest) } ;; 40 | 41 | exception Empty_xlist ;; 42 | *) 43 | let head l = 44 | match l.pointer with 45 | | Nil -> raise Empty_xlist 46 | | List (a, al) -> a;; 47 | 48 | let tail l = 49 | match l.pointer with 50 | | Nil -> raise Empty_xlist 51 | | List (a, al) -> al;; 52 | 53 | let add a l = 54 | l.pointer <- List (a, {pointer = l.pointer});; 55 | 56 | let chop l = 57 | match l.pointer with 58 | | Nil -> raise Empty_xlist 59 | | List(_, xl) -> (l.pointer <- xl.pointer);; 60 | 61 | let rec append l l' = 62 | match l.pointer with 63 | | Nil -> l.pointer <- l'.pointer 64 | | List (x, xl) -> append xl l';; 65 | 66 | let rec filter p l = 67 | match l.pointer with 68 | | Nil -> () 69 | | List (x, xl) -> 70 | (filter p xl; 71 | if p x then () 72 | else l.pointer <- xl.pointer);; 73 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/Exercise/W5_S6_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | SIMPLE USES OF REFERENCES (50/50 points) 3 | Define swap : 'a ref -> 'a ref -> unit that swaps the contents of two references. 4 | Define update : 'a ref -> ('a -> 'a) -> 'a that calls a function on the contents of a reference, updates it with the result, and returns the old value. 5 | For instance let r = ref 6 in update r (function x -> x + 1) should return 6 and set the reference to 7. 6 | Define move: 'a list ref -> 'a list ref -> unit, that removes the top argument from the first list and puts it on top of the second list. If the first list is empty, it should raise Empty. 7 | A common pattern is to use a reference to perform a computation in an imperative way, but to keep it in a local definition, completely invisible from outside the function implementation. 8 | Define reverse: 'a list -> 'a list, that has a type and an observable behaviour that look like the ones of a purely functional function, buf that use a reference internally to perform the computation. It takes a list, and returns a copy of the list whose elements are in reverse order. 9 | The only functions you can call, except from locally defined functions, are (!), (:=), ref, and move that you just defined. And you are not allowed to use pattern matching. 10 | THE GIVEN PRELUDE 11 | 12 | exception Empty ;; 13 | *) 14 | let swap ra rb = 15 | let temp = !ra in 16 | (ra := !rb; 17 | rb := temp);; 18 | 19 | let update r f = 20 | let v = !r in 21 | (r := f !r; 22 | v);; 23 | 24 | let move l1 l2 = 25 | match !l1 with 26 | | [] -> raise Empty 27 | | h::t -> 28 | (l1 := t; 29 | l2 := h::!l2) ;; 30 | 31 | let reverse l = 32 | let l2 = ref [] and l1 = ref l in 33 | let atry = 34 | try while true 35 | do move l1 l2 36 | done 37 | with _ -> () 38 | in atry; 39 | !l2;; 40 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/Exercise/W5_S6_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | READING LINES FROM THE STANDARD INPUT (10/10 points) 3 | The code given in the template is an attempt to reading a list of lines from the standard input, slightly different from the one shown in the course notes. 4 | At first sight, it behaves well. 5 | 6 | # read_lines ();; 7 | Hello 8 | mister 9 | the 10 | caml! 11 | - : string list = [ "Hello" ; "mister" ; "the" ; "caml!" ] 12 | But if you call this function several times, you get unexpected results. 13 | Study the code, to understand what is going on, compare with the example shown in the course, and then fix this code. 14 | Important note: it is not possible to implement reading functions that actually ask the user to input something in the current toplevel environment. 15 | For that, the environment defines an alternative version of read_line that simulates user interaction. Some calls will return a string, some others will (less often) raise End_of_file. 16 | *) 17 | 18 | let read_lines () = 19 | let sl = ref [] in 20 | let rec aux () = 21 | try 22 | sl := read_line () :: !sl ; 23 | aux () 24 | with 25 | End_of_file -> List.rev !sl in 26 | aux ();; 27 | 28 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S0.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S1.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S2.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S3.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S4.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S5.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W5_ALL/OCaml_MOOC_W5_S6.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/W5_S0.srt: -------------------------------------------------------------------------------- 1 | 1 2 | 00:00:08,059 --> 00:00:12,070 3 | Welcome back to this introduction to functional 4 | programming in OCaml. 5 | 6 | 2 7 | 00:00:12,070 --> 00:00:16,090 8 | This is week 5, and 9 | in this week we will discover all the imperative 10 | 11 | 3 12 | 00:00:16,090 --> 00:00:18,420 13 | features of the OCaml programming language. 14 | 15 | 4 16 | 00:00:18,420 --> 00:00:22,640 17 | Actually, OCaml is a functional language. 18 | 19 | 5 20 | 00:00:22,640 --> 00:00:26,410 21 | We have learned to do many many things up 22 | to this point, 23 | 24 | 6 25 | 00:00:26,410 --> 00:00:32,710 26 | and if you notice, you did 27 | all this using only data structures which 28 | 29 | 7 30 | 00:00:32,710 --> 00:00:35,390 31 | are immutable (we cannot modify them), 32 | 33 | 8 34 | 00:00:35,390 --> 00:00:39,350 35 | identifiers 36 | for values but these are just names for values 37 | 38 | 9 39 | 00:00:39,350 --> 00:00:40,450 40 | that you cannot change; 41 | 42 | 10 43 | 00:00:40,450 --> 00:00:44,899 44 | there is no in-place 45 | modifications (no variables, no memory cells). 46 | 47 | 11 48 | 00:00:44,899 --> 00:00:50,270 49 | And then you are using pure functions: just 50 | functions that have no side effects whatsoever. 51 | 52 | 12 53 | 00:00:50,270 --> 00:00:55,649 54 | And also the control, the flow of the control, 55 | is not changing in their way. 56 | 57 | 13 58 | 00:00:55,649 --> 00:01:00,050 59 | With this fragment 60 | of the language, we can go really very far, 61 | 62 | 14 63 | 00:01:00,050 --> 00:01:02,430 64 | doing just pure functional programming; 65 | 66 | 15 67 | 00:01:02,430 --> 00:01:05,089 68 | remember 69 | Church thesis, we can program whatever you 70 | 71 | 16 72 | 00:01:05,089 --> 00:01:05,970 73 | want. 74 | 75 | 17 76 | 00:01:05,970 --> 00:01:11,180 77 | Anyway, there are situations where imperative 78 | features can be useful: 79 | 80 | 18 81 | 00:01:11,180 --> 00:01:15,970 82 | to be more efficient 83 | in space, faster in execution. 84 | 85 | 19 86 | 00:01:15,970 --> 00:01:19,960 87 | Well, OCaml 88 | is a functional programming language, which 89 | 90 | 20 91 | 00:01:19,960 --> 00:01:21,780 92 | has a range of imperative features. 93 | 94 | 21 95 | 00:01:21,780 --> 00:01:25,070 96 | For example, 97 | we will discover that there are exceptions, 98 | 99 | 22 100 | 00:01:25,070 --> 00:01:31,950 101 | that are useful to model alteration of the 102 | flow control or capture exceptional situations. 103 | 104 | 23 105 | 00:01:31,950 --> 00:01:35,009 106 | We have operations for interacting with the 107 | outside world: 108 | 109 | 24 110 | 00:01:35,009 --> 00:01:37,970 111 | input and output which are 112 | of course modifying the state. 113 | 114 | 25 115 | 00:01:37,970 --> 00:01:41,650 116 | Then you have 117 | data structures which can be modified in place; 118 | 119 | 26 120 | 00:01:41,650 --> 00:01:47,470 121 | they are mutable and they are useful for very 122 | specific efficient imperative algorithms. 123 | 124 | 27 125 | 00:01:47,470 --> 00:01:54,130 126 | And, of course, you have specific syntax to 127 | help you write for and while loops in the usual 128 | 129 | 28 130 | 00:01:54,130 --> 00:01:55,040 131 | way. 132 | 133 | 29 134 | 00:01:55,040 --> 00:01:58,320 135 | Well basically let be just saying this: 136 | it's really your choice. 137 | 138 | 30 139 | 00:01:58,320 --> 00:02:00,549 140 | In OCaml you can 141 | be purely functional, 142 | 143 | 31 144 | 00:02:00,549 --> 00:02:04,170 145 | or you can program in 146 | fully imperative style. 147 | 148 | 32 149 | 00:02:04,170 --> 00:02:10,440 150 | In any case, the type 151 | system will be helping you stay safe. 152 | 153 | 33 154 | 00:02:10,440 --> 00:02:14,470 155 | What 156 | we'll be presenting this week: we will look 157 | 158 | 34 159 | 00:02:14,470 --> 00:02:16,230 160 | more in details at exceptions, 161 | 162 | 35 163 | 00:02:16,230 --> 00:02:20,030 164 | input/output 165 | operations and the special type we will learn 166 | 167 | 36 168 | 00:02:20,030 --> 00:02:22,209 169 | to use which is the unit type, 170 | 171 | 37 172 | 00:02:22,209 --> 00:02:25,720 173 | the mutable 174 | data structures, references which represent 175 | 176 | 38 177 | 00:02:25,720 --> 00:02:28,480 178 | variables, and for and while loops. 179 | 180 | 39 181 | 00:02:28,480 --> 00:02:33,310 182 | So, hang 183 | tight, and let's start to see these extra 184 | 185 | 40 186 | 00:02:33,310 --> 00:02:34,220 187 | imperative features. 188 | 189 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/W5_S0_fr.srt: -------------------------------------------------------------------------------- 1 | 1 2 | 00:00:08,059 --> 00:00:12,070 3 | Bienvenue dans cette nouvelle séquence du cours 4 | d'introduction à la programmation fonctionelle 5 | en OCaml. 6 | 7 | 2 8 | 00:00:12,070 --> 00:00:16,090 9 | Il s'agit de la semaine 5, et 10 | cette semaine, nous découvrons tous les 11 | 12 | 3 13 | 00:00:16,090 --> 00:00:18,420 14 | traits impératifs du langage OCaml. 15 | 16 | 4 17 | 00:00:18,420 --> 00:00:22,640 18 | En réalité, OCaml est un langage fonctionnel. 19 | 20 | 5 21 | 00:00:22,640 --> 00:00:26,410 22 | Nous avons vu comment faire de nombreuses 23 | choses avec, jusqu'à maintenant, 24 | 25 | 6 26 | 00:00:26,410 --> 00:00:32,710 27 | vous avez peut-être remarqué que 28 | nous avons tout fait en utilisant seulement 29 | des structures de données 30 | 31 | 7 32 | 00:00:32,710 --> 00:00:35,390 33 | qui sont immutables (on ne peut pas les modifier), 34 | 35 | 8 36 | 00:00:35,390 --> 00:00:39,350 37 | des identifiants pour les valeurs, 38 | qui ne sont en fait que des noms vers 39 | des valeurs 40 | 41 | 9 42 | 00:00:39,350 --> 00:00:40,450 43 | que vous ne pouvez pas changer ; 44 | 45 | 10 46 | 00:00:40,450 --> 00:00:44,899 47 | il n'y a pas non plus de modifications 48 | en place (pas de variables, pas de cellules mémoire). 49 | 50 | 11 51 | 00:00:44,899 --> 00:00:50,270 52 | Ensuite, vous avez les fonctions pures, 53 | fonctions qui n'effectuent absolument aucun effet de bord. 54 | 55 | 12 56 | 00:00:50,270 --> 00:00:55,649 57 | Également, le flot de contrôle 58 | n'est pas altéré. 59 | 60 | 13 61 | 00:00:55,649 --> 00:01:00,050 62 | Avec ce seul fragment du langage, 63 | nous pouvons aller très loin, 64 | 65 | 14 66 | 00:01:00,050 --> 00:01:02,430 67 | en faisant donc de la programmation fonctionnelle pure ; 68 | 69 | 15 70 | 00:01:02,430 --> 00:01:05,089 71 | souvenez-vous de la thèse de Church, 72 | on peut programmer ce que l'on 73 | 74 | 16 75 | 00:01:05,089 --> 00:01:05,970 76 | souhaite. 77 | 78 | 17 79 | 00:01:05,970 --> 00:01:11,180 80 | Tout de même, il y a des situations pour 81 | lesquelles des traits impératifs peuvent être utiles : 82 | 83 | 18 84 | 00:01:11,180 --> 00:01:15,970 85 | pour être plus efficace en place, 86 | plus rapide en exécution. 87 | 88 | 19 89 | 00:01:15,970 --> 00:01:19,960 90 | OCaml est un langage de programmation fonctionnelle 91 | 92 | 20 93 | 00:01:19,960 --> 00:01:21,780 94 | qui propose plusieurs fonctionnalités impératives. 95 | 96 | 21 97 | 00:01:21,780 --> 00:01:25,070 98 | Par exemple, 99 | nous verrons qu'il propose des exceptions, 100 | 101 | 22 102 | 00:01:25,070 --> 00:01:31,950 103 | qui sont utiles pour altérer le flot 104 | de contrôle ou capturer des situations exceptionnelles. 105 | 106 | 23 107 | 00:01:31,950 --> 00:01:35,009 108 | Nous avons également des opérations pour interagir 109 | avec le monde extérieur : 110 | 111 | 24 112 | 00:01:35,009 --> 00:01:37,970 113 | les entrées et sorties, qui bien 114 | sûr modifient l'état. 115 | 116 | 25 117 | 00:01:37,970 --> 00:01:41,650 118 | Puis nous avons les structures de données 119 | modifiables en place ; 120 | 121 | 26 122 | 00:01:41,650 --> 00:01:47,470 123 | elles sont mutables et utiles pour des 124 | algorithmes impératifs très efficaces. 125 | 126 | 27 127 | 00:01:47,470 --> 00:01:54,130 128 | Enfin, bien sûr, nous avons des syntaxes spécifiques 129 | pour nous aider à écrire des boucles for ou while 130 | 131 | 28 132 | 00:01:54,130 --> 00:01:55,040 133 | de façon classique. 134 | 135 | 29 136 | 00:01:55,040 --> 00:01:58,320 137 | Nous résumerons en disant cela : 138 | c'est vraiment votre choix. 139 | 140 | 30 141 | 00:01:58,320 --> 00:02:00,549 142 | En OCaml, vous pouvez être 143 | purement fonctionnel, 144 | 145 | 31 146 | 00:02:00,549 --> 00:02:04,170 147 | ou vous pouvez programmer 148 | avec un style complètement impératif. 149 | 150 | 32 151 | 00:02:04,170 --> 00:02:10,440 152 | Dans tous les cas, le système de type 153 | vous aidera à conserver la sûreté. 154 | 155 | 33 156 | 00:02:10,440 --> 00:02:14,470 157 | Ce que nous présenterons cette semaine : 158 | nous verrons 159 | 160 | 34 161 | 00:02:14,470 --> 00:02:16,230 162 | en détails les exceptions, 163 | 164 | 35 165 | 00:02:16,230 --> 00:02:20,030 166 | les opérations d'entrées / sorties 167 | ainsi qu'un type spécial 168 | 169 | 36 170 | 00:02:20,030 --> 00:02:22,209 171 | qui est le type unit. 172 | 173 | 37 174 | 00:02:22,209 --> 00:02:25,720 175 | les structures de données mutables, 176 | les références qui représentent 177 | 178 | 38 179 | 00:02:25,720 --> 00:02:28,480 180 | les variables, et les boucles for et while. 181 | 182 | 39 183 | 00:02:28,480 --> 00:02:33,310 184 | Donc, restez en ligne, et commençons à 185 | voir toutes ces fonctionnalités 186 | 187 | 40 188 | 00:02:33,310 --> 00:02:34,220 189 | impératives supplémentaires. 190 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/arraymutables.ml: -------------------------------------------------------------------------------- 1 | let a = [|0;1;2;3;4|];; 2 | 3 | a.(0);; 4 | 5 | a.(0) <- 100;; 6 | 7 | a.(0);; 8 | 9 | a;; 10 | 11 | 12 | let rotate a = 13 | let n = Array.length a in 14 | let v = a.(0) in 15 | for i = 0 to n-2 do 16 | a.(i) <- a.(i+1) 17 | done; 18 | a.(n-1)<-v;; 19 | 20 | let x = Array.init 10 (fun i -> i);; 21 | 22 | x;; 23 | 24 | rotate x;; 25 | 26 | x;; 27 | 28 | rotate x;; 29 | 30 | x;; 31 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/errorexc.ml: -------------------------------------------------------------------------------- 1 | (* division by zero *) 2 | 3/0;; 3 | 4 | (* out of bound access to mutable data structures *) 5 | 6 | let v = [|1;2;3|];; 7 | v.(0);; 8 | v.(3);; 9 | 10 | (* incomplete pattern matching *) 11 | 12 | let drop = function 13 | | a::rest -> rest;; 14 | drop [1;2;3;4;5];; 15 | drop [];; 16 | 17 | 18 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/headexc.ml: -------------------------------------------------------------------------------- 1 | exception Empty_list;; 2 | 3 | (* define a head function that uses the exception *) 4 | let head = function 5 | a::r -> a 6 | | [] -> raise Empty_list;; 7 | 8 | (* let's test *) 9 | head ['a';'b'];; 10 | head [];; 11 | 12 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/log2int.ml: -------------------------------------------------------------------------------- 1 | let log2int n = 2 | let count = ref 0 and v = ref n in 3 | while !v > 1 do 4 | count := !count + 1; 5 | v := !v/2 6 | done; 7 | !count;; 8 | 9 | log2int 16;; 10 | log2int 1024;; 11 | log2int 1000000;; 12 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/mutablerecord.ml: -------------------------------------------------------------------------------- 1 | (* RGB colors *) 2 | type color = {r: int; g:int; b:int};; 3 | let black = {r=255;g=255;b=255};; 4 | 5 | (* movable colored 2D points *) 6 | type point2D = { mutable x : int; mutable y : int ; c: color};; 7 | let origin = { x = 0; y = 0 ; c=black};; 8 | 9 | (* create a new point at offset of given one *) 10 | (* thanks to "with" we keep the same code *) 11 | let offset_h p dx = {p with x=p.x+dx};; 12 | let offset_v p dy = {p with y=p.y+dy};; 13 | 14 | (* no modification is made to the original point *) 15 | let p = offset_h origin 10;; 16 | origin;; 17 | 18 | (* start moving things around *) 19 | 20 | let move p dx dy = p.x <- p.x+dx; p.y <- p.y+dy;; 21 | 22 | (* p is modified *) 23 | 24 | p;; 25 | move p 2 2;; 26 | p;; 27 | move p (-1) (-1) ;; 28 | p;; 29 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/read_intlist.ml: -------------------------------------------------------------------------------- 1 | (* hide *) 2 | let read_int () = int_of_string (read_line()) 3 | ;; 4 | (* show *) 5 | 6 | (* read a list of integers, and stop *) 7 | (* when a non integer is entered *) 8 | 9 | let read_intlist () = 10 | (* a reference to hold the results *) 11 | let l = ref [] in 12 | (* the reading loop *) 13 | let doread() = 14 | try 15 | while true do 16 | l := (read_int ()):: !l 17 | done 18 | with _ -> () 19 | in 20 | doread(); 21 | List.rev !l 22 | ;; 23 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/recordreview.ml: -------------------------------------------------------------------------------- 1 | (* 2D points *) 2 | type point2D = { x : int; y : int };; 3 | let origin = { x = 0; y = 0 };; 4 | 5 | (* create a new point at offset of given one *) 6 | let offset_h p dx = {p with x=p.x+dx};; 7 | let offset_v p dy = {p with y=p.y+dy};; 8 | 9 | (* no modification is made to the original point *) 10 | let p = offset_h origin 10;; 11 | origin;; 12 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/refs.ml: -------------------------------------------------------------------------------- 1 | let i = ref 0;; 2 | 3 | i;; 4 | 5 | i := !i + 1;; 6 | 7 | i;; 8 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/squarecubes.ml: -------------------------------------------------------------------------------- 1 | let cubes n = Array.init n (fun i -> i*i*i);; 2 | 3 | let sqrti n = truncate (sqrt (float n));; 4 | 5 | let issquare n = let s = sqrti n in s*s =n;; 6 | 7 | let squarecubes n = 8 | let c = cubes n in 9 | for i = 0 to n-1 do 10 | if issquare c.(i) then 11 | (print_int c.(i); 12 | print_string " ") 13 | done 14 | ;; 15 | 16 | squarecubes 100;; 17 | -------------------------------------------------------------------------------- /OCaml_MOOC_W5_ALL/trywith.ml: -------------------------------------------------------------------------------- 1 | (* multiplying all values of an integer list *) 2 | (* think of a 1 million element list with a 0 at the end *) 3 | 4 | let rec multl = function 5 | [] -> 1 6 | | a::rest -> if a = 0 then 0 else a * (multl rest) 7 | ;; 8 | (* break *) 9 | 10 | (* use exceptions to return as soon as we see a zero *) 11 | 12 | exception Zero;; 13 | 14 | let multlexc l = 15 | let rec aux = function 16 | [] -> 1 17 | | a::rest -> if a = 0 then raise Zero else a * (aux rest) 18 | in 19 | try aux l with Zero -> 0;; 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/Exercise/W6_S0_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | OPENING MODULES (45/45 points) 3 | The code given in the template has been written using some values declared in three modules of the standard library. Can you find what are these three modules? When you have found them, just use open directives to have the code accepted by the type checker. Be aware that the iter function appears in multiple module and that the order in which you open the modules is important. 4 | http://caml.inria.fr/pub/docs/manual-ocaml/stdlib.html 5 | *) 6 | 7 | open Digest 8 | open String 9 | open List 10 | 11 | let print_hashes (hashes : Digest.t list) : unit = 12 | let print_hash h = h |> to_hex |> uppercase |> print_endline in 13 | iter print_hash hashes;; -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/Exercise/W6_S0_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | ACCESSING MODULES AND SUBMODULES (15/15 points) 3 | Use fully-qualified names to fix the compilation of [bfs]. (The open directive is forbidden here.) 4 | THE GIVEN PRELUDE 5 | 6 | module Tree = struct 7 | 8 | type 'a t = Leaf of 'a | Node of 'a t * 'a * 'a t 9 | 10 | module Iterator = struct 11 | 12 | type 'a path = 13 | | Top 14 | | Left of 'a path * 'a * 'a t 15 | | Right of 'a t * 'a * 'a path 16 | 17 | type 'a iterator = Loc of 'a t * 'a path 18 | 19 | exception Fail 20 | 21 | let go_left (Loc (t, p)) = 22 | match p with 23 | | Top -> raise Fail 24 | | Left (father, x, right) -> raise Fail 25 | | Right (left, x, father) -> Loc (left, Left (father, x, t)) 26 | 27 | let go_right (Loc (t, p)) = 28 | match p with 29 | | Top -> raise Fail 30 | | Left (father, x, right) -> Loc (right, Right (t, x, father)) 31 | | Right (left, x, father) -> raise Fail 32 | 33 | let go_up (Loc (t, p)) = 34 | match p with 35 | | Top -> raise Fail 36 | | Left(father, x, right) -> Loc (Node (t, x, right), father) 37 | | Right(left, x, father) -> Loc (Node (left, x, t), father) 38 | 39 | let go_first (Loc (t, p)) = 40 | match t with 41 | | Leaf _ -> raise Fail 42 | | Node (left, x, right) -> Loc (left, Left (p, x, right)) 43 | 44 | let go_second (Loc (t, p)) = 45 | match t with 46 | | Leaf _ -> raise Fail 47 | | Node (left, x, right) -> Loc (right, Right (left, x, p)) 48 | 49 | let focus (Loc ((Leaf x | Node (_, x, _)), _)) = x 50 | 51 | end 52 | 53 | end 54 | *) 55 | 56 | let bfs t = 57 | let rec aux results = function 58 | | [] -> 59 | List.rev results 60 | | l :: ls -> 61 | let results = (Tree.Iterator.focus l) :: results in 62 | try 63 | aux results (ls @ [ Tree.Iterator.go_first l; Tree.Iterator.go_second l]) 64 | with Tree.Iterator.Fail -> 65 | aux results ls 66 | in 67 | aux [] [Tree.Iterator.Loc (t, Tree.Iterator.Top)] 68 | -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/Exercise/W6_S0_3.ml: -------------------------------------------------------------------------------- 1 | (* 2 | WRAPPING FUNCTIONS IN A MODULE (10/10 points) 3 | Encapsulate the necessary values in a module named Exp so that the definition of example is accepted by the type checker. 4 | THE GIVEN PRELUDE 5 | 6 | type e = EInt of int | EMul of e * e | EAdd of e * e 7 | 8 | *) 9 | 10 | module Exp = struct 11 | let int x = EInt x 12 | 13 | let mul a b = 14 | match a, b with 15 | | EInt 0, _ | _, EInt 0 -> EInt 0 16 | | EInt 1, e | e, EInt 1 -> e 17 | | a, b -> EMul (a, b) 18 | 19 | let add a b = 20 | match a, b with 21 | | EInt 0, e | e, EInt 0 -> e 22 | | a, b -> EAdd (a, b) 23 | 24 | let rec eval = function 25 | | EInt x -> x 26 | | EAdd (l, r) -> eval l + eval r 27 | | EMul (l, r) -> eval l * eval r 28 | end 29 | 30 | let example x y z = (* don't change anything to this defintion *) 31 | Exp.int (Exp.eval (Exp.mul (Exp.int x) (Exp.add (Exp.int y) (Exp.int z)))) -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/Exercise/W6_S1_1.ml: -------------------------------------------------------------------------------- 1 | (* 2 | TYPE ABSTRACTION USING A SIGNATURE (20/20 points) 3 | Encapsulate the type and values given in the template in a module named Exp. 4 | 5 | To make e abstract, assign a signature to the module Exp that makes the type e abstract and publish the functions int, mul and add. 6 | 7 | Given that interface, the only way to build a value of type e is to use the functions int, mul add and to_string. Such functions are called smart constructors because they perform some smart operations when they build values. 8 | 9 | These smart constructors enforce the invariant that an expression represented by a value of type e is always simplified, i.e. it does not contain a subexpression of the form e * 1, 1 * e, e * 0, 0 * e, 0 + e or e + 0. 10 | 11 | The following expression should be accepted. 12 | Exp.mul (Exp.int 0) (Exp.add (Exp.int 1) (Exp.int 2)) 13 | The following expression should be rejected. 14 | Exp.EMul (Exp.EInt 0) (Exp.EAdd (Exp.EInt 1) (Exp.EInt 2)) 15 | Unfortunately, turning e into an abstract data type prevents the user from pattern matching over values of type e. To allow pattern matching while forbidding the direct application of data constructors, OCaml provides a mechanism called private types. The interested student can get more information about this advanced (off-topic) feature here. 16 | http://caml.inria.fr/pub/docs/manual-ocaml-400/manual021.html#toc76 17 | *) 18 | 19 | module Exp : sig 20 | type e 21 | val int : int -> e 22 | val mul : e -> e -> e 23 | val add : e -> e -> e 24 | val to_string : e -> string 25 | end = struct 26 | type e = EInt of int | EMul of e * e | EAdd of e * e 27 | 28 | let int x = EInt x 29 | 30 | let mul a b = 31 | match a, b with 32 | | EInt 0, _ | _, EInt 0 -> EInt 0 33 | | EInt 1, e | e, EInt 1 -> e 34 | | a, b -> EMul (a, b) 35 | 36 | let add a b = 37 | match a, b with 38 | | EInt 0, e | e, EInt 0 -> e 39 | | a, b -> EAdd (a, b) 40 | 41 | let rec to_string = function 42 | | EInt i -> string_of_int i 43 | | EMul (l, r) -> "(" ^ to_string l ^ " * " ^ to_string r ^ ")" 44 | | EAdd (l, r) -> "(" ^ to_string l ^ " + " ^ to_string r ^ ")" 45 | end 46 | 47 | (* 48 | module Exp : sig 49 | type e = private EInt of int | EMul of e * e | EAdd of e * e 50 | val int : int -> e 51 | val mul : e -> e -> e 52 | val add : e -> e -> e 53 | val to_string : e -> string 54 | end = struct 55 | type e = EInt of int | EMul of e * e | EAdd of e * e 56 | 57 | let int x = EInt x 58 | 59 | let mul a b = 60 | match a, b with 61 | | EInt 0, _ | _, EInt 0 -> EInt 0 62 | | EInt 1, e | e, EInt 1 -> e 63 | | a, b -> EMul (a, b) 64 | 65 | let add a b = 66 | match a, b with 67 | | EInt 0, e | e, EInt 0 -> e 68 | | a, b -> EAdd (a, b) 69 | 70 | let rec to_string = function 71 | | EInt i -> string_of_int i 72 | | EMul (l, r) -> "(" ^ to_string l ^ " * " ^ to_string r ^ ")" 73 | | EAdd (l, r) -> "(" ^ to_string l ^ " + " ^ to_string r ^ ")" 74 | end 75 | *) -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/Exercise/W6_S1_2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | MULTISET (25/25 points) 3 | A multiset is like a set, with the difference that a value can appear more than once. 4 | 5 | Implement a module MultiSet that implements the signature MultiSet_S. 6 | Define a function letters: string -> char MultiSet.t (where MultiSet is the module defined in the previous question). This function produces a multiset in which all characters are associated to the times they appear in the input string. 7 | Define a function anagram: string -> string -> bool that uses the previous function to tell if two words have the same multiset of characters. 8 | THE GIVEN PRELUDE 9 | 10 | module type MultiSet_S = sig 11 | 12 | (* A multi-set of type ['a t] is a collection of values of 13 | type ['a] that may occur several times. *) 14 | type 'a t 15 | 16 | (* [occurrences s x] return the number of time [x] occurs 17 | in [s]. *) 18 | val occurrences : 'a t -> 'a -> int 19 | 20 | (* The empty set has no element. There is only one unique 21 | representation of the empty set. *) 22 | val empty : 'a t 23 | 24 | (* [insert s x] returns a new multi-set that contains all 25 | elements of [s] and a new occurrence of [x]. Typically, 26 | [occurrences s x = occurrences (insert s x) x + 1]. *) 27 | val insert : 'a t -> 'a -> 'a t 28 | 29 | (* [remove s x] returns a new multi-set that contains all elements 30 | of [s] minus an occurrence of [x] (if [x] actually occurs in 31 | [s]). Typically, [occurrences s x = occurrences (remove s x) x - 32 | 1] if [occurrences s x > 0]. *) 33 | val remove : 'a t -> 'a -> 'a t 34 | 35 | end 36 | *) 37 | module MultiSet : MultiSet_S = struct 38 | type 'a t = ('a * int) list 39 | 40 | let occurrences s x = 41 | try List.assoc x s 42 | with _ -> 0 43 | 44 | let empty = [] 45 | 46 | let insert s x = 47 | (x, ((occurrences s x) + 1)) :: (List.filter (fun (str, _) -> str != x) s) 48 | 49 | let remove s x = 50 | let count = occurrences s x in 51 | if count < 2 then List.filter (fun (str, _) -> str != x) s 52 | else (x, (count - 1)) :: (List.filter (fun (str, _) -> str = x) s) 53 | end;; 54 | 55 | open MultiSet 56 | 57 | let letters word = 58 | let rec help acc str = 59 | match str with 60 | | "" -> acc 61 | | _ -> 62 | (let s = String.get str 0 in 63 | help (insert acc s) 64 | (String.sub str 1 ((String.length str) - 1))) 65 | in help empty word;; 66 | 67 | let anagram word1 word2 = 68 | let set1 = letters word1 and set2 = letters word2 in 69 | let str = word1 ^ word2 in 70 | let rec help acc i = 71 | try 72 | (let c = String.get str i in 73 | if (occurrences set1 c) = (occurrences set2 c) 74 | then acc && (help acc (i + 1)) 75 | else false) 76 | with _ -> acc 77 | in help true 0;; -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/Exercise/W6_S2.ml: -------------------------------------------------------------------------------- 1 | (* 2 | REMOVE ELEMENTS FROM DICTIONARIES (20/20 points) 3 | The following code is the program explained during the video sequence except that we have modified the interface DictSig a little bit. Now, it is possible to remove a key from a dictionary. 4 | 5 | Update the code to have it accepted by the type-checker. 6 | THE GIVEN PRELUDE 7 | 8 | module type DictSig = sig 9 | type ('key, 'value) t 10 | val empty : ('key, 'value) t 11 | val add : ('key, 'value) t -> 'key -> 'value -> ('key, 'value) t 12 | exception NotFound 13 | val lookup : ('key, 'value) t -> 'key -> 'value 14 | val remove : ('key, 'value) t -> 'key -> ('key, 'value) t 15 | end ;; 16 | *) 17 | 18 | module Dict : DictSig = struct 19 | type ('key, 'value) t = 20 | | Empty 21 | | Node of ('key, 'value) t * 'key * 'value * ('key, 'value) t 22 | 23 | let empty = Empty 24 | 25 | let rec add d k v = 26 | match d with 27 | | Empty -> Node (Empty, k, v, Empty) 28 | | Node (l, k', v', r) -> 29 | if k = k' then Node (l, k, v, r) 30 | else if k < k' then Node (add l k v, k', v', r) 31 | else Node (l, k', v', add r k v) 32 | 33 | exception NotFound 34 | 35 | let rec lookup d k = 36 | match d with 37 | | Empty -> 38 | raise NotFound 39 | | Node (l, k', v', r) -> 40 | if k = k' then v' 41 | else if k < k' then lookup l k 42 | else lookup r k 43 | 44 | let rec append d1 d2 = 45 | match d2 with 46 | | Empty -> d1 47 | | Node (l, k, v, r) -> append (append (add d1 k v) l) r 48 | 49 | let rec remove d k = 50 | match d with 51 | | Empty -> Empty 52 | | Node (l, k', v', r) -> 53 | if k = k' then append l r 54 | else Node ((remove l k), k', v', (remove r k)) 55 | 56 | end ;; 57 | 58 | -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/Exercise/W6_S3.ml: -------------------------------------------------------------------------------- 1 | (* 2 | CHAR INDEXED HASHTABLES (40/40 points) 3 | Have a look at the documentation of module Hashtbl. 4 | 5 | Implement a module CharHashedType, compatible with the HashedType signature, where type t = char. 6 | Use the module defined in the previous question to instantiate the Hashtbl.Make functor as a module CharHashtbl. 7 | Reimplement the data structure of trie from a previous exercise, so that a hash table is used to represent the association between characters and children. To do so, complete the definition of module Trie, so that it is compatible with the given signature GenericTrie, whose 'a table type is instanciated to char indexed hash tables. 8 | Be careful, a hash table is not a purely functional data structure. Therefore, it must be copied when necessary! 9 | Note: you must neither change the signature nor the types of module Trie or the tests will fail. 10 | https://www.fun-mooc.fr/courses/course-v1:parisdiderot+56002+session03/courseware/W6/W6S3/ 11 | 12 | Trie is in W3_S2_2.ml 13 | 14 | THE GIVEN PRELUDE 15 | 16 | module type GenericTrie = sig 17 | type 'a char_table 18 | type 'a trie = Trie of 'a option * 'a trie char_table 19 | val empty : unit -> 'a trie 20 | val insert : 'a trie -> string -> 'a -> 'a trie 21 | val lookup : 'a trie -> string -> 'a option 22 | end 23 | *) 24 | 25 | module CharHashedType = 26 | struct 27 | type t = char 28 | 29 | let equal c = fun x -> x = c 30 | 31 | let hash = Char.code 32 | end 33 | 34 | module CharHashtbl = Hashtbl.Make(CharHashedType) 35 | 36 | module Trie : GenericTrie 37 | with type 'a char_table = 'a CharHashtbl.t = 38 | struct 39 | type 'a char_table = 'a CharHashtbl.t 40 | type 'a trie = Trie of 'a option * 'a trie char_table 41 | 42 | let empty () = 43 | Trie (None, CharHashtbl.create 0);; 44 | 45 | let lookup trie w = 46 | let rec aux t idx = 47 | let Trie (v, table) = t in 48 | if idx = String.length w then v 49 | else 50 | try 51 | let t' = CharHashtbl.find table (String.get w idx) in 52 | aux t' (idx + 1) 53 | with _ -> None 54 | in 55 | aux trie 0 56 | 57 | let rec insert trie w v = 58 | let slen = String.length w 59 | and Trie(v',m) = trie in 60 | if slen = 0 then Trie(Some v, m) 61 | else 62 | let c = String.get w 0 63 | and s = String.sub w 1 (slen - 1) in 64 | let ot = 65 | try CharHashtbl.find m c 66 | with _ -> empty () 67 | in 68 | (CharHashtbl.replace m c (insert ot s v); 69 | Trie (v', m)) 70 | end 71 | 72 | -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/OCaml_MOOC_W6_S0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W6_ALL/OCaml_MOOC_W6_S0.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/OCaml_MOOC_W6_S1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W6_ALL/OCaml_MOOC_W6_S1.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/OCaml_MOOC_W6_S2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W6_ALL/OCaml_MOOC_W6_S2.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/OCaml_MOOC_W6_S3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W6_ALL/OCaml_MOOC_W6_S3.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/OCaml_MOOC_W6_S4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/OCaml_MOOC_W6_ALL/OCaml_MOOC_W6_S4.pdf -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/badSignature.ml: -------------------------------------------------------------------------------- 1 | module Naturals : sig 2 | (* Invariant: A value of type t is a positive integer. *) 3 | type t = int 4 | val zero : t 5 | val succ : t -> t 6 | val pred : t -> t 7 | end = struct 8 | type t = int 9 | let zero = 0 10 | (* The functions maintain the invariant. *) 11 | let succ n = if n = max_int then 0 else n + 1 12 | let pred = function 0 -> 0 | n -> n - 1 13 | end;; 14 | (* break *) 15 | open Naturals 16 | let rec add : t -> t -> t = fun x y -> 17 | if x = zero then y else succ (add (pred x) y);; 18 | let i_break_the_abstraction = pred (-1);; 19 | -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/dict.ml: -------------------------------------------------------------------------------- 1 | module type DictSig = sig 2 | type ('key, 'value) t 3 | val empty : ('key, 'value) t 4 | val add : ('key, 'value) t -> 'key -> 'value -> ('key, 'value) t 5 | exception NotFound 6 | val lookup : ('key, 'value) t -> 'key -> 'value 7 | end;; 8 | (* break *) 9 | module Dict : DictSig = struct 10 | type ('key, 'value) t = ('key * 'value) list 11 | let empty = [] 12 | let add d k v = (k, v) :: d 13 | exception NotFound 14 | let rec lookup d k = 15 | match d with 16 | | (k', v) :: d' when k = k' -> v 17 | | _ :: d -> lookup d k 18 | | [] -> raise NotFound 19 | end;; 20 | (* break *) 21 | (* The client *) 22 | module ForceArchive = struct 23 | let force = Dict.empty 24 | let force = Dict.add force "luke" 10 25 | let force = Dict.add force "yoda" 100 26 | let force = Dict.add force "darth" 1000 27 | let force_of_luke = Dict.lookup force "luke" 28 | let force_of_r2d2 = Dict.lookup force "r2d2" 29 | end;; 30 | (* break *) 31 | module Dict : DictSig = struct 32 | type ('key, 'value) t = 33 | | Empty 34 | | Node of ('key, 'value) t * 'key * 'value * ('key, 'value) t 35 | 36 | let empty = Empty 37 | 38 | let rec add d k v = 39 | match d with 40 | | Empty -> Node (Empty, k, v, Empty) 41 | | Node (l, k', v', r) -> 42 | if k = k' then Node (l, k, v, r) 43 | else if k < k' then Node (add l k v, k', v', r) 44 | else Node (l, k', v', add r k v) 45 | 46 | exception NotFound 47 | 48 | let rec lookup d k = 49 | match d with 50 | | Empty -> 51 | raise NotFound 52 | | Node (l, k', v', r) -> 53 | if k = k' then v' 54 | else if k < k' then lookup l k 55 | else lookup r k 56 | 57 | end;; 58 | (* break *) 59 | (* The same client *) 60 | module ForceArchive = struct 61 | let force = Dict.empty 62 | let force = Dict.add force "luke" 10 63 | let force = Dict.add force "yoda" 100 64 | let force = Dict.add force "darth" 1000 65 | let force_of_luke = Dict.lookup force "luke" 66 | let force_of_r2d2 = Dict.lookup force "r2d2" 67 | end;; 68 | 69 | -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/dict2.ml: -------------------------------------------------------------------------------- 1 | module type DictSig = sig 2 | type ('key, 'value) t 3 | val empty : ('key, 'value) t 4 | val add : ('key, 'value) t -> 'key -> 'value -> ('key, 'value) t 5 | exception NotFound 6 | val lookup : ('key, 'value) t -> 'key -> 'value 7 | end;; 8 | (* break *) 9 | (* The client *) 10 | module ForceArchive (Dict : DictSig) = struct 11 | let force = Dict.empty 12 | let force = Dict.add force "luke" 10 13 | let force = Dict.add force "yoda" 100 14 | let force = Dict.add force "darth" 1000 15 | let force_of_luke = Dict.lookup force "luke" 16 | let force_of_r2d2 = Dict.lookup force "r2d2" 17 | end;; 18 | (* break *) 19 | module Dict1 : DictSig = struct 20 | type ('key, 'value) t = ('key * 'value) list 21 | let empty = [] 22 | let add d k v = (k, v) :: d 23 | exception NotFound 24 | let rec lookup d k = 25 | match d with 26 | | (k', v) :: d' when k = k' -> v 27 | | _ :: d -> lookup d k 28 | | [] -> raise NotFound 29 | end;; 30 | (* break *) 31 | module Dict2 : DictSig = struct 32 | type ('key, 'value) t = 33 | | Empty 34 | | Node of ('key, 'value) t * 'key * 'value * ('key, 'value) t 35 | 36 | let empty = Empty 37 | 38 | let rec add d k v = 39 | match d with 40 | | Empty -> Node (Empty, k, v, Empty) 41 | | Node (l, k', v', r) -> 42 | if k = k' then Node (l, k, v, r) 43 | else if k < k' then Node (add l k v, k', v', r) 44 | else Node (l, k', v', add r k v) 45 | 46 | exception NotFound 47 | 48 | let rec lookup d k = 49 | match d with 50 | | Empty -> 51 | raise NotFound 52 | | Node (l, k', v', r) -> 53 | if k = k' then v' 54 | else if k < k' then lookup l k 55 | else lookup r k 56 | 57 | end;; 58 | 59 | module Client1 = ForceArchive (Dict1) 60 | module Client2 = ForceArchive (Dict2) 61 | -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/dictfunctor.ml: -------------------------------------------------------------------------------- 1 | module type DictSig = sig 2 | type key 3 | type 'value t 4 | val empty : 'value t 5 | val add : 'value t -> key -> 'value -> 'value t 6 | exception NotFound of key 7 | val lookup : 'value t -> key -> 'value 8 | end;; 9 | (* break *) 10 | module Dict (Key : sig 11 | type t 12 | val compare : t -> t -> int 13 | end) : DictSig = struct 14 | type key = Key.t 15 | type 'value t = (key * 'value) list 16 | let empty = [] 17 | let add d k v = (k, v) :: d 18 | exception NotFound of key 19 | let rec lookup d k = 20 | match d with 21 | | (k', v) :: d' when Key.compare k k' = 0 -> v 22 | | _ :: d -> lookup d k 23 | | [] -> raise (NotFound k) 24 | end;; 25 | (* break *) 26 | module Dict1 = Dict (struct 27 | type t = string 28 | let compare k1 k2 = Pervasives.compare (String.lowercase k1) (String.lowercase k2) 29 | end) 30 | (* break *) 31 | module ForceArchive (Dict : DictSig) = struct 32 | let force = Dict.empty 33 | let force = Dict.add force "luke" 10 34 | let force = Dict.add force "yoda" 100 35 | let force = Dict.add force "darth" 1000 36 | let force_of_luke = Dict.lookup force "luke" 37 | let force_of_r2d2 = Dict.lookup force "r2d2" 38 | end;; 39 | (* break *) 40 | module Dict (Key : sig 41 | type t 42 | val compare : t -> t -> int 43 | end) : DictSig with type key = Key.t = struct 44 | type key = Key.t 45 | type 'value t = (key * 'value) list 46 | let empty = [] 47 | let add d k v = (k, v) :: d 48 | exception NotFound of key 49 | let rec lookup d k = 50 | match d with 51 | | (k', v) :: d' when Key.compare k k' = 0 -> v 52 | | _ :: d -> lookup d k 53 | | [] -> raise (NotFound k) 54 | end;; 55 | (* break *) 56 | module ForceArchive (Dict : DictSig with type key = string) = struct 57 | let force = Dict.empty 58 | let force = Dict.add force "luke" 10 59 | let force = Dict.add force "yoda" 100 60 | let force = Dict.add force "darth" 1000 61 | let force_of_luke = Dict.lookup force "luke" 62 | let force_of_r2d2 = Dict.lookup force "r2d2" 63 | end;; 64 | -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/goodSignature.ml: -------------------------------------------------------------------------------- 1 | module Naturals : sig 2 | (* Invariant: A value of type t is a positive integer. *) 3 | type t 4 | val zero : t 5 | val succ : t -> t 6 | val pred : t -> t 7 | end = struct 8 | type t = int 9 | let zero = 0 10 | (* The functions maintain the invariant. *) 11 | let succ n = if n = max_int then 0 else n + 1 12 | let pred = function 0 -> 0 | n -> n - 1 13 | end;; 14 | open Naturals 15 | let rec add : t -> t -> t = fun x y -> 16 | if x = zero then y else succ (add (pred x) y);; 17 | let i_break_the_abstraction = pred (-1) 18 | -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/hideValues.ml: -------------------------------------------------------------------------------- 1 | module Naturals : sig 2 | type t 3 | val zero : t 4 | (* val return_natural : int -> t *) 5 | val succ : t -> t 6 | val pred : t -> t 7 | end = struct 8 | type t = int 9 | let zero = 0 10 | (* The following function is for internal purpose only. *) 11 | let return_natural n = assert (n >= 0 && n <= max_int); n 12 | let succ n = if n = max_int then 0 else return_natural (n + 1) 13 | let pred = function 0 -> 0 | n -> n - 1 14 | end;; 15 | 16 | Naturals.return_naturals 0;; 17 | -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/stack.ml: -------------------------------------------------------------------------------- 1 | module Stack : sig 2 | type 'a t = 'a list 3 | val empty : 'a t 4 | val push : 'a -> 'a t -> 'a t 5 | val pop : 'a t -> ('a * 'a t) option 6 | end = struct 7 | type 'a t = 'a list 8 | let empty = [] 9 | let push x s = x :: s 10 | let pop = function 11 | | [] -> None 12 | | x :: xs -> Some (x, xs) 13 | end;; 14 | -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/stackImplementation.ml: -------------------------------------------------------------------------------- 1 | module Stack = struct 2 | type 'a t = 'a list 3 | let empty = [] 4 | let push x s = x :: s 5 | let pop = function 6 | | [] -> None 7 | | x :: xs -> Some (x, xs) 8 | end;; 9 | (* break *) 10 | let s = Stack.empty;; 11 | let s = Stack.push 1 s;; 12 | let x, s = 13 | match Stack.pop s with 14 | | None -> assert false 15 | | Some (x, s) -> (x, s);; 16 | let r = Stack.pop s;; 17 | -------------------------------------------------------------------------------- /OCaml_MOOC_W6_ALL/tree.ml: -------------------------------------------------------------------------------- 1 | module Forest = struct 2 | type 'a forest = 'a list 3 | module Tree = struct 4 | type 'a tree = Leaf of 'a | Node of 'a tree forest 5 | end 6 | end;; 7 | open Forest.Tree 8 | let t = Leaf 42;; 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## The content of this course includes: 2 | 0. _Week 0:Introduction and overview:_ 3 | * S0: Introduction to the course 4 | * S1: Functional Programming:history and motivation 5 | * S2: The Ocaml language:history and key features 6 | * S3: Why the Ocaml language:meet the users 7 | * S4: Tools and development environment:first steps in Ocaml 8 | * S5: A brief showcase of some of Ocaml's features 9 | * S6: Overview of the available resouces 10 | 11 | 12 | 1. _Week 1: Basic types,definitions and functions:_ 13 | * S0: Basic Data Types 14 | * S1: More Data Types 15 | * S2: Expressions 16 | * S3: Definitions 17 | * S4: Functions 18 | * S5: Recursion 19 | 20 | 21 | 2. _Week 2: Bascic data structures :_ 22 | * S0: User-defined types 23 | * S1: Tuples 24 | * S2: Records 25 | * S3: Arrays 26 | * S4: Case study: A small typed database 27 | 28 | 29 | 3. _Week 3: More advanced data structures:_ 30 | * S0: Tagged values 31 | * S1: Recursive typess 32 | * S2: Tree-like values 33 | * S3: Case study: a story teller 34 | * S4: Polymorphic algebraic datatypes 35 | * S5: Advanced topics 36 | 37 | 38 | 4. _Week 4: Higher order functions:_ 39 | * S0: Functional Expressions 40 | * S1: Functions as First-Class Values 41 | * S2: Functions with Multiple Arguments 42 | * S3: Partial Function Application 43 | * S4: Mapping Functions on Lists 44 | * S5: Folding Functions on Lists 45 | 46 | 47 | 5. _Week 5: Exceptions, input/output and imperative constructs:_ 48 | * S0: Imperative features in OCaml 49 | * S1: Getting and handling your Exceptions 50 | * S2: Getting information in and out 51 | * S3: Sequences and iterations 52 | * S4: Mutable arrays 53 | * S5: Mutable record fields 54 | * S6: Variables, aka References 55 | 56 | 57 | 6. _Week 6: Modules and data abstraction:_ 58 | * S0: Structuring software with modules 59 | * S1: Information hiding 60 | * S2: Case study: A module for dictionaries 61 | * S3: __Functors__ 62 | * S4: Modules as compilation units 63 | -------------------------------------------------------------------------------- /ocaml-4.07-refman.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/ocaml-4.07-refman.pdf -------------------------------------------------------------------------------- /ocaml-ora-book.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugczw/Introduction-to-Functional-Programming-in-OCaml/13c4d1f92e7479f8eb10ea5d4c43a598b6676d0f/ocaml-ora-book.pdf --------------------------------------------------------------------------------