Corrigé
de l'interrogation écrite
de Programmation Fonctionnelle
I Récursivité
1.
let rec puiss x n =
if n=0 then 1.
else
let u = puiss x (n/2) in
if n mod 2 = 0 then u *. u
else u *. u *. x;;
2.
let rec serie n a x =
if n=0 then a(0)
else a(n)*.(puiss x n) +. (serie (n-1) a x);;
3.
4.*.(serie 100 (function n ->
1./.(2.*.float_of_int(n)+.1.)) (-1.));;
4.
L'expression Ocaml
serie 100 (function n -> 1.)
est bien typée. Elle a pour type float
-> float
et
c'est la fonction qui à tout x associe
la somme des x^i, pour i=0..100
II Algorithme de typage
H
E
T
f : t1 t = t1 -> t2
function
f -> function x -> f (f x) : t
x : t3 t2 = t3 -> t4 function x -> f (f x) : t2
t1 = t5 -> t4 f (f x) : t4
t1 = t6 -> t5 f : t5 -> t4
t3 = t6 f x : t5
f : t6 -> t5
x : t6
d'où: t
= t1 -> t2
t2 = t3 -> t4
t1 = t5 -> t4
t5 = t6
t4 = t5
t3 = t6
d'où: t
= t1 -> t2 = (t5 -> t4) -> (t3 -> t4) = (t6 -> t6) ->
(t6 -> t6)
d'où: twice
: ('a -> 'a) -> 'a -> 'a
(en
utilisant la règle de généralisation)
III Types algébriques
1.
let rec take n l =
if n=0 then []
else
match(l) with
[]
-> []
| t::r ->
t::(take (n-1) r);;
2.
let rec drop n l =
if n=0 then l
else
match(l) with
[] -> []
| t::r -> drop (n-1) r;;
3.
let partage l =
let n = List.length l in
((take (n/2)
l), (drop (n/2) l));;
4.
let rec fusion (l1,l2) =
match(l1,l2) with
([],l2) -> l2
| (l1,[]) -> l1
| (t1::r1,t2::r2) -> if
t1<t2 then t1::(fusion (r1,l2))
else t2::(fusion (l1,r2));;
5.
let rec tri l =
match(l) with
[] -> []
| [e] -> [e]
| _ -> let (l1,l2) = partage
l in
fusion((tri l1), (tri l2));;
IV Vous pensiez avoir fini ?
1.
type 'a expr_ens =
Vide
| Singleton of 'a
| Union of 'a expr_ens * 'a expr_ens
| Intersection of 'a expr_ens * 'a
expr_ens;;
2.
Union (Singleton 1, Singleton 2);;