1

For a loop like below:

let rec loop () = loop ()

the signature according to try.ocamlpro.com is:

val loop : unit -> 'a = <fun>

Why is this the case? loop() never stops calling itself so shouldn't it return anything?

glennsl
  • 28,186
  • 12
  • 57
  • 75
Kevin Wu
  • 1,357
  • 1
  • 15
  • 34
  • In addition to the good answers, you can think about whether `if x then 1 else loop ()` should produce a type error. What about `if x then "string" else loop ()`? – Étienne Millon Feb 19 '18 at 11:09

2 Answers2

4

Yes, it should, and that's exactly what unit -> 'a means: given any type 'a the caller asks for, the function promises to return an 'a.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • 2
    I'd frame it a bit differently (in the spirit of [partial vs. complete correctness](https://en.wikipedia.org/wiki/Correctness_(computer_science))) by saying that the function promises that _if it returns successfully_, its result will be of type `'a`. – Virgile Feb 19 '18 at 10:22
  • 1
    Even more precise would be "given a `unit`, if it returns successfully, ..." to reflect that the caller could give a non-terminating expression as an argument. – Alexey Romanov Feb 19 '18 at 10:40
  • I'd argue that in a call-by-value language such as OCaml, the termination of the evaluation of an argument is the problem of the caller and not the callee, but this is getting really off-topic. – Virgile Feb 19 '18 at 13:43
  • @AlexeyRomanov: "given a unit, if it returns successfully, ..." to reflect that the caller has to pass a unit first. It could be a method that takes no arguments. :) Or just pass the loop around as value without calling it. – Goswin von Brederlow Feb 20 '18 at 17:12
4

I'm sure someone can, and will, explain exactly how this is inferred, but it is a property of the Hindley-Milner type system and its inference algorithm that it will be able to deduce the most general type of an expression. And that is of course 'a, which will unify with anything.

So, just intuitively, if you start with the most general type, 'a, then try to find constraints that narrow it, you won't find anything in this case. The only expression that can constrain it is the recursive call, which we already assume is 'a, so there's no conflict.

glennsl
  • 28,186
  • 12
  • 57
  • 75