├── 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
--------------------------------------------------------------------------------