# 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}]"}