# Opfix ```ocaml= let rec fact = fun x -> match x with |0 -> 1 |_ -> x * fact (x-1) let fact_rec = fun f -> fun x -> match x with |0 -> 1 |_ -> x * f (x-1) fact_rec = (int -> int) -> int -> int = 'a -> 'a avec 'a = (int -> int) (* En général, *) (opfix fact_rec)= fact_rec (opfix fact_rec) opfix: ('a->'a) -> 'a opfix fact_rec : 'a (opfix fact_rec) 2 (* Réussite de Anatole *) (opfix fact_rec) 2 fact_rec (opfix fact_rec) 2 2 * (opfix fact_rec) 1 2 * (fact_rec (opfix fact_rec) 1) 2 * 1 * (opfix fact_rec 0) 2 * 1 * (fact_rec (opfix fact_rec) 0) 2 * 1 * 1 2 opfix f = f (opfix f) opfix : ('α->'α)->'α Manière de définir quelque chose qui ressemble à opfix en OCaml : ```ocaml= let rec opfix f () = f (opfix f) (* Les unit sont là pour geler *) (* Type : ((unit -> 'a) -> 'a) -> unit -> 'a*) let fact_rec f x = if x = 0 then 1 else x * f () (x -1) (* Type : (unit -> int -> int) -> int -> int*) opfix fact_rec () 3 (* S'évalue en 6 *) ``` Autre méthode : ```ocaml= let opfix f x = f f x ;; let rec_fact f x = match x with | 0 -> 1 | _ -> x * (f f (x-1)) ;; let fact = opfix rec_fact ;; Printf.printf "%d\n" (fact 3) ;; ``` Récursif terminal, via CPS, malgré un double appel récursif. ```ocaml= let taille_cps a = let rec taille a cont = match a with | Vide -> cont 0 | Noeud(_, g, d) -> taille g (fun r -> taille d (fun r' -> cont (r + r' + 1))) in taille a (fun x -> x) ```
{"metaMigratedAt":"2023-06-15T16:53:52.125Z","metaMigratedFrom":"Content","title":"Opfix","breaks":true,"contributors":"[{\"id\":\"eb84254e-7341-4076-96c3-8eae4dcc91e4\",\"add\":709,\"del\":9},{\"id\":null,\"add\":14,\"del\":6},{\"id\":\"a66e72a0-84f5-4dbe-996c-93a8ba9547d4\",\"add\":544,\"del\":3},{\"id\":\"d9b4b8d8-f52c-4c9d-8146-1526e80b1aa0\",\"add\":199,\"del\":0},{\"id\":\"66339bfe-f00c-46e1-a9af-798b02d1721b\",\"add\":26,\"del\":0}]"}
Expand menu