Convert tail call to OCaml

I was told in the class that the following function is not tail recursive due to the Boolean operator being evaluated after the recursive call:

let rec exists p = function
    [] -> false
  | a::l -> p a || exists p l

But that doesn't hit the stack on the ten millionth list of sizes, and what’s more, this is an implementation in the standard library. If it were not tail recursive, there would be no reason to use this form instead of the seemingly equivalent and explicitly tail recursive

let rec exists p = function
    [] -> false
  | a::l -> if p a then true else exists p l

therefore, it seems that the OCaml compiler is able to optimize logical operators in simple cases like this to take advantage of tail recursion. But I noticed that if I switch the order of the operands like this

let rec exists p = function
    [] -> false
  | a::l -> exists p l || p a

10- . , , OCaml , , , op if. - ?

+5
3

, , .

, || if/then/else, , :

  • , a || b if a then true else b
  • a || b , .. if a || b then c else d -, - if a then goto c else if b then goto c else d, goto c c ( if a then c else if b then c c). , , .

. || Psequor, asmcomp/cmmgen.ml (( 1), (2)] bytecomp/bytegen.ml ( , -, ).

: , , , OCaml - "", " ", "", . , , . "" .

, , , OCaml : -annot foo.annot ( foo.ml), , , , . , caml-mode Emacs M-x caml-types-show-call exists , || , " ", p x " " ".

+9

:

let rec add_result p = function
  [] -> 0
| a::l -> p a + add_result p l

, .

|| , A || B if A then true else B, ,

let rec exists p = function
  [] -> false
| a::l -> p a || exists p l

,

let rec exists p = function
  [] -> false
| a::l -> if p a then true else exists p l

.

let rec exists p = function
  [] -> false
| a::l -> exists p l || p a

let rec exists p = function
  [] -> false
| a::l -> if exist p l then true else p a

.

+8

. , , OCaml, . , (||): rhs , , , , , rhs , (||). . , , , OCaml. OCaml, , true || succ 5.

+2

All Articles